update copyright year range in GDB files
[external/binutils.git] / sim / aarch64 / simulator.c
1 /* simulator.c -- Interface for the AArch64 simulator.
2
3    Copyright (C) 2015-2017 Free Software Foundation, Inc.
4
5    Contributed by Red Hat.
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <sys/types.h>
27 #include <math.h>
28 #include <time.h>
29 #include <limits.h>
30
31 #include "simulator.h"
32 #include "cpustate.h"
33 #include "memory.h"
34
35 #define NO_SP 0
36 #define SP_OK 1
37
38 #define TST(_flag)   (aarch64_test_CPSR_bit (cpu, _flag))
39 #define IS_SET(_X)   (TST (( _X )) ? 1 : 0)
40 #define IS_CLEAR(_X) (TST (( _X )) ? 0 : 1)
41
42 /* Space saver macro.  */
43 #define INSTR(HIGH, LOW) uimm (aarch64_get_instr (cpu), (HIGH), (LOW))
44
45 #define HALT_UNALLOC                                                    \
46   do                                                                    \
47     {                                                                   \
48       TRACE_DISASM (cpu, aarch64_get_PC (cpu));                         \
49       TRACE_INSN (cpu,                                                  \
50                   "Unallocated instruction detected at sim line %d,"    \
51                   " exe addr %" PRIx64,                                 \
52                   __LINE__, aarch64_get_PC (cpu));                      \
53       sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),\
54                        sim_stopped, SIM_SIGILL);                        \
55     }                                                                   \
56   while (0)
57
58 #define HALT_NYI                                                        \
59   do                                                                    \
60     {                                                                   \
61       TRACE_DISASM (cpu, aarch64_get_PC (cpu));                         \
62       TRACE_INSN (cpu,                                                  \
63                   "Unimplemented instruction detected at sim line %d,"  \
64                   " exe addr %" PRIx64,                                 \
65                   __LINE__, aarch64_get_PC (cpu));                      \
66       if (! TRACE_ANY_P (cpu))                                          \
67         sim_io_eprintf (CPU_STATE (cpu), "SIM Error: Unimplemented instruction: %#08x\n", \
68                         aarch64_get_instr (cpu));                       \
69       sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),\
70                        sim_stopped, SIM_SIGABRT);                       \
71     }                                                                   \
72   while (0)
73
74 #define NYI_assert(HI, LO, EXPECTED)                                    \
75   do                                                                    \
76     {                                                                   \
77       if (INSTR ((HI), (LO)) != (EXPECTED))                             \
78         HALT_NYI;                                                       \
79     }                                                                   \
80   while (0)
81
82 /* Helper functions used by expandLogicalImmediate.  */
83
84 /* for i = 1, ... N result<i-1> = 1 other bits are zero  */
85 static inline uint64_t
86 ones (int N)
87 {
88   return (N == 64 ? (uint64_t)-1UL : ((1UL << N) - 1));
89 }
90
91 /* result<0> to val<N>  */
92 static inline uint64_t
93 pickbit (uint64_t val, int N)
94 {
95   return pickbits64 (val, N, N);
96 }
97
98 static uint64_t
99 expand_logical_immediate (uint32_t S, uint32_t R, uint32_t N)
100 {
101   uint64_t mask;
102   uint64_t imm;
103   unsigned simd_size;
104
105   /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
106      (in other words, right rotated by R), then replicated. */
107   if (N != 0)
108     {
109       simd_size = 64;
110       mask = 0xffffffffffffffffull;
111     }
112   else
113     {
114       switch (S)
115         {
116         case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32;           break;
117         case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
118         case 0x30 ... 0x37: /* 110xxx */ simd_size =  8; S &= 0x7; break;
119         case 0x38 ... 0x3b: /* 1110xx */ simd_size =  4; S &= 0x3; break;
120         case 0x3c ... 0x3d: /* 11110x */ simd_size =  2; S &= 0x1; break;
121         default: return 0;
122         }
123       mask = (1ull << simd_size) - 1;
124       /* Top bits are IGNORED.  */
125       R &= simd_size - 1;
126     }
127
128   /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected.  */
129   if (S == simd_size - 1)
130     return 0;
131
132   /* S+1 consecutive bits to 1.  */
133   /* NOTE: S can't be 63 due to detection above.  */
134   imm = (1ull << (S + 1)) - 1;
135
136   /* Rotate to the left by simd_size - R.  */
137   if (R != 0)
138     imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
139
140   /* Replicate the value according to SIMD size.  */
141   switch (simd_size)
142     {
143     case  2: imm = (imm <<  2) | imm;
144     case  4: imm = (imm <<  4) | imm;
145     case  8: imm = (imm <<  8) | imm;
146     case 16: imm = (imm << 16) | imm;
147     case 32: imm = (imm << 32) | imm;
148     case 64: break;
149     default: return 0;
150     }
151
152   return imm;
153 }
154
155 /* Instr[22,10] encodes N immr and imms. we want a lookup table
156    for each possible combination i.e. 13 bits worth of int entries.  */
157 #define  LI_TABLE_SIZE  (1 << 13)
158 static uint64_t LITable[LI_TABLE_SIZE];
159
160 void
161 aarch64_init_LIT_table (void)
162 {
163   unsigned index;
164
165   for (index = 0; index < LI_TABLE_SIZE; index++)
166     {
167       uint32_t N    = uimm (index, 12, 12);
168       uint32_t immr = uimm (index, 11, 6);
169       uint32_t imms = uimm (index, 5, 0);
170
171       LITable [index] = expand_logical_immediate (imms, immr, N);
172     }
173 }
174
175 static void
176 dexNotify (sim_cpu *cpu)
177 {
178   /* instr[14,0] == type : 0 ==> method entry, 1 ==> method reentry
179                            2 ==> exit Java, 3 ==> start next bytecode.  */
180   uint32_t type = INSTR (14, 0);
181
182   TRACE_EVENTS (cpu, "Notify Insn encountered, type = 0x%x", type);
183
184   switch (type)
185     {
186     case 0:
187       /* aarch64_notifyMethodEntry (aarch64_get_reg_u64 (cpu, R23, 0),
188          aarch64_get_reg_u64 (cpu, R22, 0));  */
189       break;
190     case 1:
191       /* aarch64_notifyMethodReentry (aarch64_get_reg_u64 (cpu, R23, 0),
192          aarch64_get_reg_u64 (cpu, R22, 0));  */
193       break;
194     case 2:
195       /* aarch64_notifyMethodExit ();  */
196       break;
197     case 3:
198       /* aarch64_notifyBCStart (aarch64_get_reg_u64 (cpu, R23, 0),
199          aarch64_get_reg_u64 (cpu, R22, 0));  */
200       break;
201     }
202 }
203
204 /* secondary decode within top level groups  */
205
206 static void
207 dexPseudo (sim_cpu *cpu)
208 {
209   /* assert instr[28,27] = 00
210
211      We provide 2 pseudo instructions:
212
213      HALT stops execution of the simulator causing an immediate
214      return to the x86 code which entered it.
215
216      CALLOUT initiates recursive entry into x86 code.  A register
217      argument holds the address of the x86 routine.  Immediate
218      values in the instruction identify the number of general
219      purpose and floating point register arguments to be passed
220      and the type of any value to be returned.  */
221
222   uint32_t PSEUDO_HALT      =  0xE0000000U;
223   uint32_t PSEUDO_CALLOUT   =  0x00018000U;
224   uint32_t PSEUDO_CALLOUTR  =  0x00018001U;
225   uint32_t PSEUDO_NOTIFY    =  0x00014000U;
226   uint32_t dispatch;
227
228   if (aarch64_get_instr (cpu) == PSEUDO_HALT)
229     {
230       TRACE_EVENTS (cpu, " Pseudo Halt Instruction");
231       sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
232                        sim_stopped, SIM_SIGTRAP);
233     }
234
235   dispatch = INSTR (31, 15);
236
237   /* We do not handle callouts at the moment.  */
238   if (dispatch == PSEUDO_CALLOUT || dispatch == PSEUDO_CALLOUTR)
239     {
240       TRACE_EVENTS (cpu, " Callout");
241       sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
242                        sim_stopped, SIM_SIGABRT);
243     }
244
245   else if (dispatch == PSEUDO_NOTIFY)
246     dexNotify (cpu);
247
248   else
249     HALT_UNALLOC;
250 }
251
252 /* Load-store single register (unscaled offset)
253    These instructions employ a base register plus an unscaled signed
254    9 bit offset.
255
256    N.B. the base register (source) can be Xn or SP. all other
257    registers may not be SP.  */
258
259 /* 32 bit load 32 bit unscaled signed 9 bit.  */
260 static void
261 ldur32 (sim_cpu *cpu, int32_t offset)
262 {
263   unsigned rn = INSTR (9, 5);
264   unsigned rt = INSTR (4, 0);
265
266   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
267   aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32
268                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
269                         + offset));
270 }
271
272 /* 64 bit load 64 bit unscaled signed 9 bit.  */
273 static void
274 ldur64 (sim_cpu *cpu, int32_t offset)
275 {
276   unsigned rn = INSTR (9, 5);
277   unsigned rt = INSTR (4, 0);
278
279   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
280   aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64
281                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
282                         + offset));
283 }
284
285 /* 32 bit load zero-extended byte unscaled signed 9 bit.  */
286 static void
287 ldurb32 (sim_cpu *cpu, int32_t offset)
288 {
289   unsigned rn = INSTR (9, 5);
290   unsigned rt = INSTR (4, 0);
291
292   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
293   aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u8
294                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
295                         + offset));
296 }
297
298 /* 32 bit load sign-extended byte unscaled signed 9 bit.  */
299 static void
300 ldursb32 (sim_cpu *cpu, int32_t offset)
301 {
302   unsigned rn = INSTR (9, 5);
303   unsigned rt = INSTR (4, 0);
304
305   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
306   aarch64_set_reg_u64 (cpu, rt, NO_SP, (uint32_t) aarch64_get_mem_s8
307                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
308                         + offset));
309 }
310
311 /* 64 bit load sign-extended byte unscaled signed 9 bit.  */
312 static void
313 ldursb64 (sim_cpu *cpu, int32_t offset)
314 {
315   unsigned rn = INSTR (9, 5);
316   unsigned rt = INSTR (4, 0);
317
318   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
319   aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s8
320                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
321                         + offset));
322 }
323
324 /* 32 bit load zero-extended short unscaled signed 9 bit  */
325 static void
326 ldurh32 (sim_cpu *cpu, int32_t offset)
327 {
328   unsigned rn = INSTR (9, 5);
329   unsigned rd = INSTR (4, 0);
330
331   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
332   aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_mem_u16
333                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
334                         + offset));
335 }
336
337 /* 32 bit load sign-extended short unscaled signed 9 bit  */
338 static void
339 ldursh32 (sim_cpu *cpu, int32_t offset)
340 {
341   unsigned rn = INSTR (9, 5);
342   unsigned rd = INSTR (4, 0);
343
344   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
345   aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) aarch64_get_mem_s16
346                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
347                         + offset));
348 }
349
350 /* 64 bit load sign-extended short unscaled signed 9 bit  */
351 static void
352 ldursh64 (sim_cpu *cpu, int32_t offset)
353 {
354   unsigned rn = INSTR (9, 5);
355   unsigned rt = INSTR (4, 0);
356
357   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
358   aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s16
359                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
360                         + offset));
361 }
362
363 /* 64 bit load sign-extended word unscaled signed 9 bit  */
364 static void
365 ldursw (sim_cpu *cpu, int32_t offset)
366 {
367   unsigned rn = INSTR (9, 5);
368   unsigned rd = INSTR (4, 0);
369
370   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
371   aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) aarch64_get_mem_s32
372                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
373                         + offset));
374 }
375
376 /* N.B. with stores the value in source is written to the address
377    identified by source2 modified by offset.  */
378
379 /* 32 bit store 32 bit unscaled signed 9 bit.  */
380 static void
381 stur32 (sim_cpu *cpu, int32_t offset)
382 {
383   unsigned rn = INSTR (9, 5);
384   unsigned rd = INSTR (4, 0);
385
386   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
387   aarch64_set_mem_u32 (cpu,
388                        aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
389                        aarch64_get_reg_u32 (cpu, rd, NO_SP));
390 }
391
392 /* 64 bit store 64 bit unscaled signed 9 bit  */
393 static void
394 stur64 (sim_cpu *cpu, int32_t offset)
395 {
396   unsigned rn = INSTR (9, 5);
397   unsigned rd = INSTR (4, 0);
398
399   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
400   aarch64_set_mem_u64 (cpu,
401                        aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
402                        aarch64_get_reg_u64 (cpu, rd, NO_SP));
403 }
404
405 /* 32 bit store byte unscaled signed 9 bit  */
406 static void
407 sturb (sim_cpu *cpu, int32_t offset)
408 {
409   unsigned rn = INSTR (9, 5);
410   unsigned rd = INSTR (4, 0);
411
412   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
413   aarch64_set_mem_u8 (cpu,
414                       aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
415                       aarch64_get_reg_u8 (cpu, rd, NO_SP));
416 }
417
418 /* 32 bit store short unscaled signed 9 bit  */
419 static void
420 sturh (sim_cpu *cpu, int32_t offset)
421 {
422   unsigned rn = INSTR (9, 5);
423   unsigned rd = INSTR (4, 0);
424
425   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
426   aarch64_set_mem_u16 (cpu,
427                        aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
428                        aarch64_get_reg_u16 (cpu, rd, NO_SP));
429 }
430
431 /* Load single register pc-relative label
432    Offset is a signed 19 bit immediate count in words
433    rt may not be SP.  */
434
435 /* 32 bit pc-relative load  */
436 static void
437 ldr32_pcrel (sim_cpu *cpu, int32_t offset)
438 {
439   unsigned rd = INSTR (4, 0);
440
441   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
442   aarch64_set_reg_u64 (cpu, rd, NO_SP,
443                        aarch64_get_mem_u32
444                        (cpu, aarch64_get_PC (cpu) + offset * 4));
445 }
446
447 /* 64 bit pc-relative load  */
448 static void
449 ldr_pcrel (sim_cpu *cpu, int32_t offset)
450 {
451   unsigned rd = INSTR (4, 0);
452
453   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
454   aarch64_set_reg_u64 (cpu, rd, NO_SP,
455                        aarch64_get_mem_u64
456                        (cpu, aarch64_get_PC (cpu) + offset * 4));
457 }
458
459 /* sign extended 32 bit pc-relative load  */
460 static void
461 ldrsw_pcrel (sim_cpu *cpu, int32_t offset)
462 {
463   unsigned rd = INSTR (4, 0);
464
465   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
466   aarch64_set_reg_u64 (cpu, rd, NO_SP,
467                        aarch64_get_mem_s32
468                        (cpu, aarch64_get_PC (cpu) + offset * 4));
469 }
470
471 /* float pc-relative load  */
472 static void
473 fldrs_pcrel (sim_cpu *cpu, int32_t offset)
474 {
475   unsigned int rd = INSTR (4, 0);
476
477   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
478   aarch64_set_vec_u32 (cpu, rd, 0,
479                        aarch64_get_mem_u32
480                        (cpu, aarch64_get_PC (cpu) + offset * 4));
481 }
482
483 /* double pc-relative load  */
484 static void
485 fldrd_pcrel (sim_cpu *cpu, int32_t offset)
486 {
487   unsigned int st = INSTR (4, 0);
488
489   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
490   aarch64_set_vec_u64 (cpu, st, 0,
491                        aarch64_get_mem_u64
492                        (cpu, aarch64_get_PC (cpu) + offset * 4));
493 }
494
495 /* long double pc-relative load.  */
496 static void
497 fldrq_pcrel (sim_cpu *cpu, int32_t offset)
498 {
499   unsigned int st = INSTR (4, 0);
500   uint64_t addr = aarch64_get_PC (cpu) + offset * 4;
501   FRegister a;
502
503   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
504   aarch64_get_mem_long_double (cpu, addr, & a);
505   aarch64_set_FP_long_double (cpu, st, a);
506 }
507
508 /* This can be used to scale an offset by applying
509    the requisite shift. the second argument is either
510    16, 32 or 64.  */
511
512 #define SCALE(_offset, _elementSize) \
513     ((_offset) << ScaleShift ## _elementSize)
514
515 /* This can be used to optionally scale a register derived offset
516    by applying the requisite shift as indicated by the Scaling
517    argument.  The second argument is either Byte, Short, Word
518    or Long. The third argument is either Scaled or Unscaled.
519    N.B. when _Scaling is Scaled the shift gets ANDed with
520    all 1s while when it is Unscaled it gets ANDed with 0.  */
521
522 #define OPT_SCALE(_offset, _elementType, _Scaling) \
523   ((_offset) << (_Scaling ? ScaleShift ## _elementType : 0))
524
525 /* This can be used to zero or sign extend a 32 bit register derived
526    value to a 64 bit value.  the first argument must be the value as
527    a uint32_t and the second must be either UXTW or SXTW. The result
528    is returned as an int64_t.  */
529
530 static inline int64_t
531 extend (uint32_t value, Extension extension)
532 {
533   union
534   {
535     uint32_t u;
536     int32_t   n;
537   } x;
538
539   /* A branchless variant of this ought to be possible.  */
540   if (extension == UXTW || extension == NoExtension)
541     return value;
542
543   x.u = value;
544   return x.n;
545 }
546
547 /* Scalar Floating Point
548
549    FP load/store single register (4 addressing modes)
550
551    N.B. the base register (source) can be the stack pointer.
552    The secondary source register (source2) can only be an Xn register.  */
553
554 /* Load 32 bit unscaled signed 9 bit with pre- or post-writeback.  */
555 static void
556 fldrs_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
557 {
558   unsigned rn = INSTR (9, 5);
559   unsigned st = INSTR (4, 0);
560   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
561
562   if (wb != Post)
563     address += offset;
564
565   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
566   aarch64_set_vec_u32 (cpu, st, 0, aarch64_get_mem_u32 (cpu, address));
567   if (wb == Post)
568     address += offset;
569
570   if (wb != NoWriteBack)
571     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
572 }
573
574 /* Load 8 bit with unsigned 12 bit offset.  */
575 static void
576 fldrb_abs (sim_cpu *cpu, uint32_t offset)
577 {
578   unsigned rd = INSTR (4, 0);
579   unsigned rn = INSTR (9, 5);
580   uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset;
581
582   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
583   aarch64_set_vec_u8 (cpu, rd, 0, aarch64_get_mem_u32 (cpu, addr));
584 }
585
586 /* Load 16 bit scaled unsigned 12 bit.  */
587 static void
588 fldrh_abs (sim_cpu *cpu, uint32_t offset)
589 {
590   unsigned rd = INSTR (4, 0);
591   unsigned rn = INSTR (9, 5);
592   uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 16);
593
594   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
595   aarch64_set_vec_u16 (cpu, rd, 0, aarch64_get_mem_u16 (cpu, addr));
596 }
597
598 /* Load 32 bit scaled unsigned 12 bit.  */
599 static void
600 fldrs_abs (sim_cpu *cpu, uint32_t offset)
601 {
602   unsigned rd = INSTR (4, 0);
603   unsigned rn = INSTR (9, 5);
604   uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 32);
605
606   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
607   aarch64_set_vec_u32 (cpu, rd, 0, aarch64_get_mem_u32 (cpu, addr));
608 }
609
610 /* Load 64 bit scaled unsigned 12 bit.  */
611 static void
612 fldrd_abs (sim_cpu *cpu, uint32_t offset)
613 {
614   unsigned rd = INSTR (4, 0);
615   unsigned rn = INSTR (9, 5);
616   uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 64);
617
618   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
619   aarch64_set_vec_u64 (cpu, rd, 0, aarch64_get_mem_u64 (cpu, addr));
620 }
621
622 /* Load 128 bit scaled unsigned 12 bit.  */
623 static void
624 fldrq_abs (sim_cpu *cpu, uint32_t offset)
625 {
626   unsigned rd = INSTR (4, 0);
627   unsigned rn = INSTR (9, 5);
628   uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 128);
629
630   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
631   aarch64_set_vec_u64 (cpu, rd, 0, aarch64_get_mem_u64 (cpu, addr));
632   aarch64_set_vec_u64 (cpu, rd, 1, aarch64_get_mem_u64 (cpu, addr + 8));
633 }
634
635 /* Load 32 bit scaled or unscaled zero- or sign-extended
636    32-bit register offset.  */
637 static void
638 fldrs_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
639 {
640   unsigned rm = INSTR (20, 16);
641   unsigned rn = INSTR (9, 5);
642   unsigned st = INSTR (4, 0);
643   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
644   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
645   uint64_t displacement = OPT_SCALE (extended, 32, scaling);
646
647   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
648   aarch64_set_vec_u32 (cpu, st, 0, aarch64_get_mem_u32
649                        (cpu, address + displacement));
650 }
651
652 /* Load 64 bit unscaled signed 9 bit with pre- or post-writeback.  */
653 static void
654 fldrd_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
655 {
656   unsigned rn = INSTR (9, 5);
657   unsigned st = INSTR (4, 0);
658   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
659
660   if (wb != Post)
661     address += offset;
662
663   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
664   aarch64_set_vec_u64 (cpu, st, 0, aarch64_get_mem_u64 (cpu, address));
665
666   if (wb == Post)
667     address += offset;
668
669   if (wb != NoWriteBack)
670     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
671 }
672
673 /* Load 64 bit scaled or unscaled zero- or sign-extended 32-bit register offset.  */
674 static void
675 fldrd_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
676 {
677   unsigned rm = INSTR (20, 16);
678   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
679   uint64_t displacement = OPT_SCALE (extended, 64, scaling);
680
681   fldrd_wb (cpu, displacement, NoWriteBack);
682 }
683
684 /* Load 128 bit unscaled signed 9 bit with pre- or post-writeback.  */
685 static void
686 fldrq_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
687 {
688   FRegister a;
689   unsigned rn = INSTR (9, 5);
690   unsigned st = INSTR (4, 0);
691   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
692
693   if (wb != Post)
694     address += offset;
695
696   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
697   aarch64_get_mem_long_double (cpu, address, & a);
698   aarch64_set_FP_long_double (cpu, st, a);
699
700   if (wb == Post)
701     address += offset;
702
703   if (wb != NoWriteBack)
704     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
705 }
706
707 /* Load 128 bit scaled or unscaled zero- or sign-extended 32-bit register offset  */
708 static void
709 fldrq_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
710 {
711   unsigned rm = INSTR (20, 16);
712   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
713   uint64_t displacement = OPT_SCALE (extended, 128, scaling);
714
715   fldrq_wb (cpu, displacement, NoWriteBack);
716 }
717
718 /* Memory Access
719
720    load-store single register
721    There are four addressing modes available here which all employ a
722    64 bit source (base) register.
723
724    N.B. the base register (source) can be the stack pointer.
725    The secondary source register (source2)can only be an Xn register.
726
727    Scaled, 12-bit, unsigned immediate offset, without pre- and
728    post-index options.
729    Unscaled, 9-bit, signed immediate offset with pre- or post-index
730    writeback.
731    scaled or unscaled 64-bit register offset.
732    scaled or unscaled 32-bit extended register offset.
733
734    All offsets are assumed to be raw from the decode i.e. the
735    simulator is expected to adjust scaled offsets based on the
736    accessed data size with register or extended register offset
737    versions the same applies except that in the latter case the
738    operation may also require a sign extend.
739
740    A separate method is provided for each possible addressing mode.  */
741
742 /* 32 bit load 32 bit scaled unsigned 12 bit  */
743 static void
744 ldr32_abs (sim_cpu *cpu, uint32_t offset)
745 {
746   unsigned rn = INSTR (9, 5);
747   unsigned rt = INSTR (4, 0);
748
749   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
750   /* The target register may not be SP but the source may be.  */
751   aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32
752                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
753                         + SCALE (offset, 32)));
754 }
755
756 /* 32 bit load 32 bit unscaled signed 9 bit with pre- or post-writeback.  */
757 static void
758 ldr32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
759 {
760   unsigned rn = INSTR (9, 5);
761   unsigned rt = INSTR (4, 0);
762   uint64_t address;
763
764   if (rn == rt && wb != NoWriteBack)
765     HALT_UNALLOC;
766
767   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
768
769   if (wb != Post)
770     address += offset;
771
772   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
773   aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32 (cpu, address));
774
775   if (wb == Post)
776     address += offset;
777
778   if (wb != NoWriteBack)
779     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
780 }
781
782 /* 32 bit load 32 bit scaled or unscaled
783    zero- or sign-extended 32-bit register offset  */
784 static void
785 ldr32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
786 {
787   unsigned rm = INSTR (20, 16);
788   unsigned rn = INSTR (9, 5);
789   unsigned rt = INSTR (4, 0);
790   /* rn may reference SP, rm and rt must reference ZR  */
791
792   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
793   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
794   uint64_t displacement =  OPT_SCALE (extended, 32, scaling);
795
796   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
797   aarch64_set_reg_u64 (cpu, rt, NO_SP,
798                        aarch64_get_mem_u32 (cpu, address + displacement));
799 }
800
801 /* 64 bit load 64 bit scaled unsigned 12 bit  */
802 static void
803 ldr_abs (sim_cpu *cpu, uint32_t offset)
804 {
805   unsigned rn = INSTR (9, 5);
806   unsigned rt = INSTR (4, 0);
807
808   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
809   /* The target register may not be SP but the source may be.  */
810   aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64
811                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
812                         + SCALE (offset, 64)));
813 }
814
815 /* 64 bit load 64 bit unscaled signed 9 bit with pre- or post-writeback.  */
816 static void
817 ldr_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
818 {
819   unsigned rn = INSTR (9, 5);
820   unsigned rt = INSTR (4, 0);
821   uint64_t address;
822
823   if (rn == rt && wb != NoWriteBack)
824     HALT_UNALLOC;
825
826   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
827
828   if (wb != Post)
829     address += offset;
830
831   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
832   aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64 (cpu, address));
833
834   if (wb == Post)
835     address += offset;
836
837   if (wb != NoWriteBack)
838     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
839 }
840
841 /* 64 bit load 64 bit scaled or unscaled zero-
842    or sign-extended 32-bit register offset.  */
843 static void
844 ldr_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
845 {
846   unsigned rm = INSTR (20, 16);
847   unsigned rn = INSTR (9, 5);
848   unsigned rt = INSTR (4, 0);
849   /* rn may reference SP, rm and rt must reference ZR  */
850
851   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
852   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
853   uint64_t displacement =  OPT_SCALE (extended, 64, scaling);
854
855   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
856   aarch64_set_reg_u64 (cpu, rt, NO_SP,
857                        aarch64_get_mem_u64 (cpu, address + displacement));
858 }
859
860 /* 32 bit load zero-extended byte scaled unsigned 12 bit.  */
861 static void
862 ldrb32_abs (sim_cpu *cpu, uint32_t offset)
863 {
864   unsigned rn = INSTR (9, 5);
865   unsigned rt = INSTR (4, 0);
866
867   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
868   /* The target register may not be SP but the source may be
869      there is no scaling required for a byte load.  */
870   aarch64_set_reg_u64 (cpu, rt, NO_SP,
871                        aarch64_get_mem_u8
872                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset));
873 }
874
875 /* 32 bit load zero-extended byte unscaled signed 9 bit with pre- or post-writeback.  */
876 static void
877 ldrb32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
878 {
879   unsigned rn = INSTR (9, 5);
880   unsigned rt = INSTR (4, 0);
881   uint64_t address;
882
883   if (rn == rt && wb != NoWriteBack)
884     HALT_UNALLOC;
885
886   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
887
888   if (wb != Post)
889     address += offset;
890
891   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
892   aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u8 (cpu, address));
893
894   if (wb == Post)
895     address += offset;
896
897   if (wb != NoWriteBack)
898     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
899 }
900
901 /* 32 bit load zero-extended byte scaled or unscaled zero-
902    or sign-extended 32-bit register offset.  */
903 static void
904 ldrb32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
905 {
906   unsigned rm = INSTR (20, 16);
907   unsigned rn = INSTR (9, 5);
908   unsigned rt = INSTR (4, 0);
909   /* rn may reference SP, rm and rt must reference ZR  */
910
911   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
912   int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
913                                  extension);
914
915   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
916   /* There is no scaling required for a byte load.  */
917   aarch64_set_reg_u64 (cpu, rt, NO_SP,
918                        aarch64_get_mem_u8 (cpu, address + displacement));
919 }
920
921 /* 64 bit load sign-extended byte unscaled signed 9 bit
922    with pre- or post-writeback.  */
923 static void
924 ldrsb_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
925 {
926   unsigned rn = INSTR (9, 5);
927   unsigned rt = INSTR (4, 0);
928   uint64_t address;
929   int64_t val;
930
931   if (rn == rt && wb != NoWriteBack)
932     HALT_UNALLOC;
933
934   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
935
936   if (wb != Post)
937     address += offset;
938
939   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
940   val = aarch64_get_mem_s8 (cpu, address);
941   aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
942
943   if (wb == Post)
944     address += offset;
945
946   if (wb != NoWriteBack)
947     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
948 }
949
950 /* 64 bit load sign-extended byte scaled unsigned 12 bit.  */
951 static void
952 ldrsb_abs (sim_cpu *cpu, uint32_t offset)
953 {
954   ldrsb_wb (cpu, offset, NoWriteBack);
955 }
956
957 /* 64 bit load sign-extended byte scaled or unscaled zero-
958    or sign-extended 32-bit register offset.  */
959 static void
960 ldrsb_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
961 {
962   unsigned rm = INSTR (20, 16);
963   unsigned rn = INSTR (9, 5);
964   unsigned rt = INSTR (4, 0);
965   /* rn may reference SP, rm and rt must reference ZR  */
966
967   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
968   int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
969                                  extension);
970   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
971   /* There is no scaling required for a byte load.  */
972   aarch64_set_reg_s64 (cpu, rt, NO_SP,
973                        aarch64_get_mem_s8 (cpu, address + displacement));
974 }
975
976 /* 32 bit load zero-extended short scaled unsigned 12 bit.  */
977 static void
978 ldrh32_abs (sim_cpu *cpu, uint32_t offset)
979 {
980   unsigned rn = INSTR (9, 5);
981   unsigned rt = INSTR (4, 0);
982   uint32_t val;
983
984   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
985   /* The target register may not be SP but the source may be.  */
986   val = aarch64_get_mem_u16 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
987                              + SCALE (offset, 16));
988   aarch64_set_reg_u32 (cpu, rt, NO_SP, val);
989 }
990
991 /* 32 bit load zero-extended short unscaled signed 9 bit
992    with pre- or post-writeback.  */
993 static void
994 ldrh32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
995 {
996   unsigned rn = INSTR (9, 5);
997   unsigned rt = INSTR (4, 0);
998   uint64_t address;
999
1000   if (rn == rt && wb != NoWriteBack)
1001     HALT_UNALLOC;
1002
1003   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1004
1005   if (wb != Post)
1006     address += offset;
1007
1008   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1009   aarch64_set_reg_u32 (cpu, rt, NO_SP, aarch64_get_mem_u16 (cpu, address));
1010
1011   if (wb == Post)
1012     address += offset;
1013
1014   if (wb != NoWriteBack)
1015     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
1016 }
1017
1018 /* 32 bit load zero-extended short scaled or unscaled zero-
1019    or sign-extended 32-bit register offset.  */
1020 static void
1021 ldrh32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
1022 {
1023   unsigned rm = INSTR (20, 16);
1024   unsigned rn = INSTR (9, 5);
1025   unsigned rt = INSTR (4, 0);
1026   /* rn may reference SP, rm and rt must reference ZR  */
1027
1028   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1029   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
1030   uint64_t displacement =  OPT_SCALE (extended, 16, scaling);
1031
1032   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1033   aarch64_set_reg_u32 (cpu, rt, NO_SP,
1034                        aarch64_get_mem_u16 (cpu, address + displacement));
1035 }
1036
1037 /* 32 bit load sign-extended short scaled unsigned 12 bit.  */
1038 static void
1039 ldrsh32_abs (sim_cpu *cpu, uint32_t offset)
1040 {
1041   unsigned rn = INSTR (9, 5);
1042   unsigned rt = INSTR (4, 0);
1043   int32_t val;
1044
1045   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1046   /* The target register may not be SP but the source may be.  */
1047   val = aarch64_get_mem_s16 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
1048                              + SCALE (offset, 16));
1049   aarch64_set_reg_s32 (cpu, rt, NO_SP, val);
1050 }
1051
1052 /* 32 bit load sign-extended short unscaled signed 9 bit
1053    with pre- or post-writeback.  */
1054 static void
1055 ldrsh32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
1056 {
1057   unsigned rn = INSTR (9, 5);
1058   unsigned rt = INSTR (4, 0);
1059   uint64_t address;
1060
1061   if (rn == rt && wb != NoWriteBack)
1062     HALT_UNALLOC;
1063
1064   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1065
1066   if (wb != Post)
1067     address += offset;
1068
1069   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1070   aarch64_set_reg_s32 (cpu, rt, NO_SP,
1071                        (int32_t) aarch64_get_mem_s16 (cpu, address));
1072
1073   if (wb == Post)
1074     address += offset;
1075
1076   if (wb != NoWriteBack)
1077     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
1078 }
1079
1080 /* 32 bit load sign-extended short scaled or unscaled zero-
1081    or sign-extended 32-bit register offset.  */
1082 static void
1083 ldrsh32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
1084 {
1085   unsigned rm = INSTR (20, 16);
1086   unsigned rn = INSTR (9, 5);
1087   unsigned rt = INSTR (4, 0);
1088   /* rn may reference SP, rm and rt must reference ZR  */
1089
1090   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1091   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
1092   uint64_t displacement =  OPT_SCALE (extended, 16, scaling);
1093
1094   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1095   aarch64_set_reg_s32 (cpu, rt, NO_SP,
1096                        (int32_t) aarch64_get_mem_s16
1097                        (cpu, address + displacement));
1098 }
1099
1100 /* 64 bit load sign-extended short scaled unsigned 12 bit.  */
1101 static void
1102 ldrsh_abs (sim_cpu *cpu, uint32_t offset)
1103 {
1104   unsigned rn = INSTR (9, 5);
1105   unsigned rt = INSTR (4, 0);
1106   int64_t val;
1107
1108   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1109   /* The target register may not be SP but the source may be.  */
1110   val = aarch64_get_mem_s16  (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
1111                               + SCALE (offset, 16));
1112   aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
1113 }
1114
1115 /* 64 bit load sign-extended short unscaled signed 9 bit
1116    with pre- or post-writeback.  */
1117 static void
1118 ldrsh64_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
1119 {
1120   unsigned rn = INSTR (9, 5);
1121   unsigned rt = INSTR (4, 0);
1122   uint64_t address;
1123   int64_t val;
1124
1125   if (rn == rt && wb != NoWriteBack)
1126     HALT_UNALLOC;
1127
1128   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1129   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1130
1131   if (wb != Post)
1132     address += offset;
1133
1134   val = aarch64_get_mem_s16 (cpu, address);
1135   aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
1136
1137   if (wb == Post)
1138     address += offset;
1139
1140   if (wb != NoWriteBack)
1141     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
1142 }
1143
1144 /* 64 bit load sign-extended short scaled or unscaled zero-
1145    or sign-extended 32-bit register offset.  */
1146 static void
1147 ldrsh_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
1148 {
1149   unsigned rm = INSTR (20, 16);
1150   unsigned rn = INSTR (9, 5);
1151   unsigned rt = INSTR (4, 0);
1152
1153   /* rn may reference SP, rm and rt must reference ZR  */
1154
1155   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1156   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
1157   uint64_t displacement = OPT_SCALE (extended, 16, scaling);
1158   int64_t val;
1159
1160   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1161   val = aarch64_get_mem_s16 (cpu, address + displacement);
1162   aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
1163 }
1164
1165 /* 64 bit load sign-extended 32 bit scaled unsigned 12 bit.  */
1166 static void
1167 ldrsw_abs (sim_cpu *cpu, uint32_t offset)
1168 {
1169   unsigned rn = INSTR (9, 5);
1170   unsigned rt = INSTR (4, 0);
1171   int64_t val;
1172
1173   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1174   val = aarch64_get_mem_s32 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
1175                              + SCALE (offset, 32));
1176   /* The target register may not be SP but the source may be.  */
1177   return aarch64_set_reg_s64 (cpu, rt, NO_SP, val);
1178 }
1179
1180 /* 64 bit load sign-extended 32 bit unscaled signed 9 bit
1181    with pre- or post-writeback.  */
1182 static void
1183 ldrsw_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
1184 {
1185   unsigned rn = INSTR (9, 5);
1186   unsigned rt = INSTR (4, 0);
1187   uint64_t address;
1188
1189   if (rn == rt && wb != NoWriteBack)
1190     HALT_UNALLOC;
1191
1192   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1193
1194   if (wb != Post)
1195     address += offset;
1196
1197   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1198   aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s32 (cpu, address));
1199
1200   if (wb == Post)
1201     address += offset;
1202
1203   if (wb != NoWriteBack)
1204     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
1205 }
1206
1207 /* 64 bit load sign-extended 32 bit scaled or unscaled zero-
1208    or sign-extended 32-bit register offset.  */
1209 static void
1210 ldrsw_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
1211 {
1212   unsigned rm = INSTR (20, 16);
1213   unsigned rn = INSTR (9, 5);
1214   unsigned rt = INSTR (4, 0);
1215   /* rn may reference SP, rm and rt must reference ZR  */
1216
1217   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1218   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
1219   uint64_t displacement =  OPT_SCALE (extended, 32, scaling);
1220
1221   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1222   aarch64_set_reg_s64 (cpu, rt, NO_SP,
1223                        aarch64_get_mem_s32 (cpu, address + displacement));
1224 }
1225
1226 /* N.B. with stores the value in source is written to the
1227    address identified by source2 modified by source3/offset.  */
1228
1229 /* 32 bit store scaled unsigned 12 bit.  */
1230 static void
1231 str32_abs (sim_cpu *cpu, uint32_t offset)
1232 {
1233   unsigned rn = INSTR (9, 5);
1234   unsigned rt = INSTR (4, 0);
1235
1236   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1237   /* The target register may not be SP but the source may be.  */
1238   aarch64_set_mem_u32 (cpu, (aarch64_get_reg_u64 (cpu, rn, SP_OK)
1239                              + SCALE (offset, 32)),
1240                        aarch64_get_reg_u32 (cpu, rt, NO_SP));
1241 }
1242
1243 /* 32 bit store unscaled signed 9 bit with pre- or post-writeback.  */
1244 static void
1245 str32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
1246 {
1247   unsigned rn = INSTR (9, 5);
1248   unsigned rt = INSTR (4, 0);
1249   uint64_t address;
1250
1251   if (rn == rt && wb != NoWriteBack)
1252     HALT_UNALLOC;
1253
1254   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1255   if (wb != Post)
1256     address += offset;
1257
1258   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1259   aarch64_set_mem_u32 (cpu, address, aarch64_get_reg_u32 (cpu, rt, NO_SP));
1260
1261   if (wb == Post)
1262     address += offset;
1263
1264   if (wb != NoWriteBack)
1265     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
1266 }
1267
1268 /* 32 bit store scaled or unscaled zero- or
1269    sign-extended 32-bit register offset.  */
1270 static void
1271 str32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
1272 {
1273   unsigned rm = INSTR (20, 16);
1274   unsigned rn = INSTR (9, 5);
1275   unsigned rt = INSTR (4, 0);
1276
1277   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1278   int64_t  extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
1279   uint64_t displacement = OPT_SCALE (extended, 32, scaling);
1280
1281   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1282   aarch64_set_mem_u32 (cpu, address + displacement,
1283                        aarch64_get_reg_u64 (cpu, rt, NO_SP));
1284 }
1285
1286 /* 64 bit store scaled unsigned 12 bit.  */
1287 static void
1288 str_abs (sim_cpu *cpu, uint32_t offset)
1289 {
1290   unsigned rn = INSTR (9, 5);
1291   unsigned rt = INSTR (4, 0);
1292
1293   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1294   aarch64_set_mem_u64 (cpu,
1295                        aarch64_get_reg_u64 (cpu, rn, SP_OK)
1296                        + SCALE (offset, 64),
1297                        aarch64_get_reg_u64 (cpu, rt, NO_SP));
1298 }
1299
1300 /* 64 bit store unscaled signed 9 bit with pre- or post-writeback.  */
1301 static void
1302 str_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
1303 {
1304   unsigned rn = INSTR (9, 5);
1305   unsigned rt = INSTR (4, 0);
1306   uint64_t address;
1307
1308   if (rn == rt && wb != NoWriteBack)
1309     HALT_UNALLOC;
1310
1311   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1312
1313   if (wb != Post)
1314     address += offset;
1315
1316   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1317   aarch64_set_mem_u64 (cpu, address, aarch64_get_reg_u64 (cpu, rt, NO_SP));
1318
1319   if (wb == Post)
1320     address += offset;
1321
1322   if (wb != NoWriteBack)
1323     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
1324 }
1325
1326 /* 64 bit store scaled or unscaled zero-
1327    or sign-extended 32-bit register offset.  */
1328 static void
1329 str_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
1330 {
1331   unsigned rm = INSTR (20, 16);
1332   unsigned rn = INSTR (9, 5);
1333   unsigned rt = INSTR (4, 0);
1334   /* rn may reference SP, rm and rt must reference ZR  */
1335
1336   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1337   int64_t   extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
1338                                extension);
1339   uint64_t displacement = OPT_SCALE (extended, 64, scaling);
1340
1341   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1342   aarch64_set_mem_u64 (cpu, address + displacement,
1343                        aarch64_get_reg_u64 (cpu, rt, NO_SP));
1344 }
1345
1346 /* 32 bit store byte scaled unsigned 12 bit.  */
1347 static void
1348 strb_abs (sim_cpu *cpu, uint32_t offset)
1349 {
1350   unsigned rn = INSTR (9, 5);
1351   unsigned rt = INSTR (4, 0);
1352
1353   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1354   /* The target register may not be SP but the source may be.
1355      There is no scaling required for a byte load.  */
1356   aarch64_set_mem_u8 (cpu,
1357                       aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
1358                       aarch64_get_reg_u8 (cpu, rt, NO_SP));
1359 }
1360
1361 /* 32 bit store byte unscaled signed 9 bit with pre- or post-writeback.  */
1362 static void
1363 strb_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
1364 {
1365   unsigned rn = INSTR (9, 5);
1366   unsigned rt = INSTR (4, 0);
1367   uint64_t address;
1368
1369   if (rn == rt && wb != NoWriteBack)
1370     HALT_UNALLOC;
1371
1372   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1373
1374   if (wb != Post)
1375     address += offset;
1376
1377   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1378   aarch64_set_mem_u8 (cpu, address, aarch64_get_reg_u8 (cpu, rt, NO_SP));
1379
1380   if (wb == Post)
1381     address += offset;
1382
1383   if (wb != NoWriteBack)
1384     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
1385 }
1386
1387 /* 32 bit store byte scaled or unscaled zero-
1388    or sign-extended 32-bit register offset.  */
1389 static void
1390 strb_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
1391 {
1392   unsigned rm = INSTR (20, 16);
1393   unsigned rn = INSTR (9, 5);
1394   unsigned rt = INSTR (4, 0);
1395   /* rn may reference SP, rm and rt must reference ZR  */
1396
1397   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1398   int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
1399                                  extension);
1400
1401   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1402   /* There is no scaling required for a byte load.  */
1403   aarch64_set_mem_u8 (cpu, address + displacement,
1404                       aarch64_get_reg_u8 (cpu, rt, NO_SP));
1405 }
1406
1407 /* 32 bit store short scaled unsigned 12 bit.  */
1408 static void
1409 strh_abs (sim_cpu *cpu, uint32_t offset)
1410 {
1411   unsigned rn = INSTR (9, 5);
1412   unsigned rt = INSTR (4, 0);
1413
1414   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1415   /* The target register may not be SP but the source may be.  */
1416   aarch64_set_mem_u16 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK)
1417                        + SCALE (offset, 16),
1418                        aarch64_get_reg_u16 (cpu, rt, NO_SP));
1419 }
1420
1421 /* 32 bit store short unscaled signed 9 bit with pre- or post-writeback.  */
1422 static void
1423 strh_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
1424 {
1425   unsigned rn = INSTR (9, 5);
1426   unsigned rt = INSTR (4, 0);
1427   uint64_t address;
1428
1429   if (rn == rt && wb != NoWriteBack)
1430     HALT_UNALLOC;
1431
1432   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1433
1434   if (wb != Post)
1435     address += offset;
1436
1437   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1438   aarch64_set_mem_u16 (cpu, address, aarch64_get_reg_u16 (cpu, rt, NO_SP));
1439
1440   if (wb == Post)
1441     address += offset;
1442
1443   if (wb != NoWriteBack)
1444     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
1445 }
1446
1447 /* 32 bit store short scaled or unscaled zero-
1448    or sign-extended 32-bit register offset.  */
1449 static void
1450 strh_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
1451 {
1452   unsigned rm = INSTR (20, 16);
1453   unsigned rn = INSTR (9, 5);
1454   unsigned rt = INSTR (4, 0);
1455   /* rn may reference SP, rm and rt must reference ZR  */
1456
1457   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1458   int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension);
1459   uint64_t displacement =  OPT_SCALE (extended, 16, scaling);
1460
1461   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1462   aarch64_set_mem_u16 (cpu, address + displacement,
1463                        aarch64_get_reg_u16 (cpu, rt, NO_SP));
1464 }
1465
1466 /* Prefetch unsigned 12 bit.  */
1467 static void
1468 prfm_abs (sim_cpu *cpu, uint32_t offset)
1469 {
1470   /* instr[4,0] = prfop : 00000 ==> PLDL1KEEP, 00001 ==> PLDL1STRM,
1471                           00010 ==> PLDL2KEEP, 00001 ==> PLDL2STRM,
1472                           00100 ==> PLDL3KEEP, 00101 ==> PLDL3STRM,
1473                           10000 ==> PSTL1KEEP, 10001 ==> PSTL1STRM,
1474                           10010 ==> PSTL2KEEP, 10001 ==> PSTL2STRM,
1475                           10100 ==> PSTL3KEEP, 10101 ==> PSTL3STRM,
1476                           ow ==> UNALLOC
1477      PrfOp prfop = prfop (instr, 4, 0);
1478      uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK)
1479      + SCALE (offset, 64).  */
1480
1481   /* TODO : implement prefetch of address.  */
1482 }
1483
1484 /* Prefetch scaled or unscaled zero- or sign-extended 32-bit register offset.  */
1485 static void
1486 prfm_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
1487 {
1488   /* instr[4,0] = prfop : 00000 ==> PLDL1KEEP, 00001 ==> PLDL1STRM,
1489                           00010 ==> PLDL2KEEP, 00001 ==> PLDL2STRM,
1490                           00100 ==> PLDL3KEEP, 00101 ==> PLDL3STRM,
1491                           10000 ==> PSTL1KEEP, 10001 ==> PSTL1STRM,
1492                           10010 ==> PSTL2KEEP, 10001 ==> PSTL2STRM,
1493                           10100 ==> PSTL3KEEP, 10101 ==> PSTL3STRM,
1494                           ow ==> UNALLOC
1495      rn may reference SP, rm may only reference ZR
1496      PrfOp prfop = prfop (instr, 4, 0);
1497      uint64_t base = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1498      int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
1499                                 extension);
1500      uint64_t displacement =  OPT_SCALE (extended, 64, scaling);
1501      uint64_t address = base + displacement.  */
1502
1503   /* TODO : implement prefetch of address  */
1504 }
1505
1506 /* 64 bit pc-relative prefetch.  */
1507 static void
1508 prfm_pcrel (sim_cpu *cpu, int32_t offset)
1509 {
1510   /* instr[4,0] = prfop : 00000 ==> PLDL1KEEP, 00001 ==> PLDL1STRM,
1511                           00010 ==> PLDL2KEEP, 00001 ==> PLDL2STRM,
1512                           00100 ==> PLDL3KEEP, 00101 ==> PLDL3STRM,
1513                           10000 ==> PSTL1KEEP, 10001 ==> PSTL1STRM,
1514                           10010 ==> PSTL2KEEP, 10001 ==> PSTL2STRM,
1515                           10100 ==> PSTL3KEEP, 10101 ==> PSTL3STRM,
1516                           ow ==> UNALLOC
1517      PrfOp prfop = prfop (instr, 4, 0);
1518      uint64_t address = aarch64_get_PC (cpu) + offset.  */
1519
1520   /* TODO : implement this  */
1521 }
1522
1523 /* Load-store exclusive.  */
1524
1525 static void
1526 ldxr (sim_cpu *cpu)
1527 {
1528   unsigned rn = INSTR (9, 5);
1529   unsigned rt = INSTR (4, 0);
1530   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1531   int size = INSTR (31, 30);
1532   /* int ordered = INSTR (15, 15);  */
1533   /* int exclusive = ! INSTR (23, 23);  */
1534
1535   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1536   switch (size)
1537     {
1538     case 0:
1539       aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u8 (cpu, address));
1540       break;
1541     case 1:
1542       aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u16 (cpu, address));
1543       break;
1544     case 2:
1545       aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32 (cpu, address));
1546       break;
1547     case 3:
1548       aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64 (cpu, address));
1549       break;
1550     }
1551 }
1552
1553 static void
1554 stxr (sim_cpu *cpu)
1555 {
1556   unsigned rn = INSTR (9, 5);
1557   unsigned rt = INSTR (4, 0);
1558   unsigned rs = INSTR (20, 16);
1559   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1560   int      size = INSTR (31, 30);
1561   uint64_t data = aarch64_get_reg_u64 (cpu, rt, NO_SP);
1562
1563   switch (size)
1564     {
1565     case 0: aarch64_set_mem_u8 (cpu, address, data); break;
1566     case 1: aarch64_set_mem_u16 (cpu, address, data); break;
1567     case 2: aarch64_set_mem_u32 (cpu, address, data); break;
1568     case 3: aarch64_set_mem_u64 (cpu, address, data); break;
1569     }
1570
1571   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1572   aarch64_set_reg_u64 (cpu, rs, NO_SP, 0); /* Always exclusive...  */
1573 }
1574
1575 static void
1576 dexLoadLiteral (sim_cpu *cpu)
1577 {
1578   /* instr[29,27] == 011
1579      instr[25,24] == 00
1580      instr[31,30:26] = opc: 000 ==> LDRW,  001 ==> FLDRS
1581                             010 ==> LDRX,  011 ==> FLDRD
1582                             100 ==> LDRSW, 101 ==> FLDRQ
1583                             110 ==> PRFM, 111 ==> UNALLOC
1584      instr[26] ==> V : 0 ==> GReg, 1 ==> FReg
1585      instr[23, 5] == simm19  */
1586
1587   /* unsigned rt = INSTR (4, 0);  */
1588   uint32_t dispatch = (INSTR (31, 30) << 1) | INSTR (26, 26);
1589   int32_t imm = simm32 (aarch64_get_instr (cpu), 23, 5);
1590
1591   switch (dispatch)
1592     {
1593     case 0: ldr32_pcrel (cpu, imm); break;
1594     case 1: fldrs_pcrel (cpu, imm); break;
1595     case 2: ldr_pcrel   (cpu, imm); break;
1596     case 3: fldrd_pcrel (cpu, imm); break;
1597     case 4: ldrsw_pcrel (cpu, imm); break;
1598     case 5: fldrq_pcrel (cpu, imm); break;
1599     case 6: prfm_pcrel  (cpu, imm); break;
1600     case 7:
1601     default:
1602       HALT_UNALLOC;
1603     }
1604 }
1605
1606 /* Immediate arithmetic
1607    The aimm argument is a 12 bit unsigned value or a 12 bit unsigned
1608    value left shifted by 12 bits (done at decode).
1609
1610    N.B. the register args (dest, source) can normally be Xn or SP.
1611    the exception occurs for flag setting instructions which may
1612    only use Xn for the output (dest).  */
1613
1614 /* 32 bit add immediate.  */
1615 static void
1616 add32 (sim_cpu *cpu, uint32_t aimm)
1617 {
1618   unsigned rn = INSTR (9, 5);
1619   unsigned rd = INSTR (4, 0);
1620
1621   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1622   aarch64_set_reg_u64 (cpu, rd, SP_OK,
1623                        aarch64_get_reg_u32 (cpu, rn, SP_OK) + aimm);
1624 }
1625
1626 /* 64 bit add immediate.  */
1627 static void
1628 add64 (sim_cpu *cpu, uint32_t aimm)
1629 {
1630   unsigned rn = INSTR (9, 5);
1631   unsigned rd = INSTR (4, 0);
1632
1633   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1634   aarch64_set_reg_u64 (cpu, rd, SP_OK,
1635                        aarch64_get_reg_u64 (cpu, rn, SP_OK) + aimm);
1636 }
1637
1638 static void
1639 set_flags_for_add32 (sim_cpu *cpu, int32_t value1, int32_t value2)
1640 {
1641   int32_t   result = value1 + value2;
1642   int64_t   sresult = (int64_t) value1 + (int64_t) value2;
1643   uint64_t  uresult = (uint64_t)(uint32_t) value1
1644     + (uint64_t)(uint32_t) value2;
1645   uint32_t  flags = 0;
1646
1647   if (result == 0)
1648     flags |= Z;
1649
1650   if (result & (1 << 31))
1651     flags |= N;
1652
1653   if (uresult != result)
1654     flags |= C;
1655
1656   if (sresult != result)
1657     flags |= V;
1658
1659   aarch64_set_CPSR (cpu, flags);
1660 }
1661
1662 #define NEG(a) (((a) & signbit) == signbit)
1663 #define POS(a) (((a) & signbit) == 0)
1664
1665 static void
1666 set_flags_for_add64 (sim_cpu *cpu, uint64_t value1, uint64_t value2)
1667 {
1668   uint64_t result = value1 + value2;
1669   uint32_t flags = 0;
1670   uint64_t signbit = 1ULL << 63;
1671
1672   if (result == 0)
1673     flags |= Z;
1674
1675   if (NEG (result))
1676     flags |= N;
1677
1678   if (   (NEG (value1) && NEG (value2))
1679       || (NEG (value1) && POS (result))
1680       || (NEG (value2) && POS (result)))
1681     flags |= C;
1682
1683   if (   (NEG (value1) && NEG (value2) && POS (result))
1684       || (POS (value1) && POS (value2) && NEG (result)))
1685     flags |= V;
1686
1687   aarch64_set_CPSR (cpu, flags);
1688 }
1689
1690 static void
1691 set_flags_for_sub32 (sim_cpu *cpu, uint32_t value1, uint32_t value2)
1692 {
1693   uint32_t result = value1 - value2;
1694   uint32_t flags = 0;
1695   uint32_t signbit = 1U << 31;
1696
1697   if (result == 0)
1698     flags |= Z;
1699
1700   if (NEG (result))
1701     flags |= N;
1702
1703   if (   (NEG (value1) && POS (value2))
1704       || (NEG (value1) && POS (result))
1705       || (POS (value2) && POS (result)))
1706     flags |= C;
1707
1708   if (   (NEG (value1) && POS (value2) && POS (result))
1709       || (POS (value1) && NEG (value2) && NEG (result)))
1710     flags |= V;
1711
1712   aarch64_set_CPSR (cpu, flags);
1713 }
1714
1715 static void
1716 set_flags_for_sub64 (sim_cpu *cpu, uint64_t value1, uint64_t value2)
1717 {
1718   uint64_t result = value1 - value2;
1719   uint32_t flags = 0;
1720   uint64_t signbit = 1ULL << 63;
1721
1722   if (result == 0)
1723     flags |= Z;
1724
1725   if (NEG (result))
1726     flags |= N;
1727
1728   if (   (NEG (value1) && POS (value2))
1729       || (NEG (value1) && POS (result))
1730       || (POS (value2) && POS (result)))
1731     flags |= C;
1732
1733   if (   (NEG (value1) && POS (value2) && POS (result))
1734       || (POS (value1) && NEG (value2) && NEG (result)))
1735     flags |= V;
1736
1737   aarch64_set_CPSR (cpu, flags);
1738 }
1739
1740 static void
1741 set_flags_for_binop32 (sim_cpu *cpu, uint32_t result)
1742 {
1743   uint32_t flags = 0;
1744
1745   if (result == 0)
1746     flags |= Z;
1747   else
1748     flags &= ~ Z;
1749
1750   if (result & (1 << 31))
1751     flags |= N;
1752   else
1753     flags &= ~ N;
1754
1755   aarch64_set_CPSR (cpu, flags);
1756 }
1757
1758 static void
1759 set_flags_for_binop64 (sim_cpu *cpu, uint64_t result)
1760 {
1761   uint32_t flags = 0;
1762
1763   if (result == 0)
1764     flags |= Z;
1765   else
1766     flags &= ~ Z;
1767
1768   if (result & (1ULL << 63))
1769     flags |= N;
1770   else
1771     flags &= ~ N;
1772
1773   aarch64_set_CPSR (cpu, flags);
1774 }
1775
1776 /* 32 bit add immediate set flags.  */
1777 static void
1778 adds32 (sim_cpu *cpu, uint32_t aimm)
1779 {
1780   unsigned rn = INSTR (9, 5);
1781   unsigned rd = INSTR (4, 0);
1782   /* TODO : do we need to worry about signs here?  */
1783   int32_t value1 = aarch64_get_reg_s32 (cpu, rn, SP_OK);
1784
1785   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1786   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + aimm);
1787   set_flags_for_add32 (cpu, value1, aimm);
1788 }
1789
1790 /* 64 bit add immediate set flags.  */
1791 static void
1792 adds64 (sim_cpu *cpu, uint32_t aimm)
1793 {
1794   unsigned rn = INSTR (9, 5);
1795   unsigned rd = INSTR (4, 0);
1796   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1797   uint64_t value2 = aimm;
1798
1799   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1800   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
1801   set_flags_for_add64 (cpu, value1, value2);
1802 }
1803
1804 /* 32 bit sub immediate.  */
1805 static void
1806 sub32 (sim_cpu *cpu, uint32_t aimm)
1807 {
1808   unsigned rn = INSTR (9, 5);
1809   unsigned rd = INSTR (4, 0);
1810
1811   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1812   aarch64_set_reg_u64 (cpu, rd, SP_OK,
1813                        aarch64_get_reg_u32 (cpu, rn, SP_OK) - aimm);
1814 }
1815
1816 /* 64 bit sub immediate.  */
1817 static void
1818 sub64 (sim_cpu *cpu, uint32_t aimm)
1819 {
1820   unsigned rn = INSTR (9, 5);
1821   unsigned rd = INSTR (4, 0);
1822
1823   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1824   aarch64_set_reg_u64 (cpu, rd, SP_OK,
1825                        aarch64_get_reg_u64 (cpu, rn, SP_OK) - aimm);
1826 }
1827
1828 /* 32 bit sub immediate set flags.  */
1829 static void
1830 subs32 (sim_cpu *cpu, uint32_t aimm)
1831 {
1832   unsigned rn = INSTR (9, 5);
1833   unsigned rd = INSTR (4, 0);
1834   uint32_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1835   uint32_t value2 = aimm;
1836
1837   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1838   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
1839   set_flags_for_sub32 (cpu, value1, value2);
1840 }
1841
1842 /* 64 bit sub immediate set flags.  */
1843 static void
1844 subs64 (sim_cpu *cpu, uint32_t aimm)
1845 {
1846   unsigned rn = INSTR (9, 5);
1847   unsigned rd = INSTR (4, 0);
1848   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
1849   uint32_t value2 = aimm;
1850
1851   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1852   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
1853   set_flags_for_sub64 (cpu, value1, value2);
1854 }
1855
1856 /* Data Processing Register.  */
1857
1858 /* First two helpers to perform the shift operations.  */
1859
1860 static inline uint32_t
1861 shifted32 (uint32_t value, Shift shift, uint32_t count)
1862 {
1863   switch (shift)
1864     {
1865     default:
1866     case LSL:
1867       return (value << count);
1868     case LSR:
1869       return (value >> count);
1870     case ASR:
1871       {
1872         int32_t svalue = value;
1873         return (svalue >> count);
1874       }
1875     case ROR:
1876       {
1877         uint32_t top = value >> count;
1878         uint32_t bottom = value << (32 - count);
1879         return (bottom | top);
1880       }
1881     }
1882 }
1883
1884 static inline uint64_t
1885 shifted64 (uint64_t value, Shift shift, uint32_t count)
1886 {
1887   switch (shift)
1888     {
1889     default:
1890     case LSL:
1891       return (value << count);
1892     case LSR:
1893       return (value >> count);
1894     case ASR:
1895       {
1896         int64_t svalue = value;
1897         return (svalue >> count);
1898       }
1899     case ROR:
1900       {
1901         uint64_t top = value >> count;
1902         uint64_t bottom = value << (64 - count);
1903         return (bottom | top);
1904       }
1905     }
1906 }
1907
1908 /* Arithmetic shifted register.
1909    These allow an optional LSL, ASR or LSR to the second source
1910    register with a count up to the register bit count.
1911
1912    N.B register args may not be SP.  */
1913
1914 /* 32 bit ADD shifted register.  */
1915 static void
1916 add32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
1917 {
1918   unsigned rm = INSTR (20, 16);
1919   unsigned rn = INSTR (9, 5);
1920   unsigned rd = INSTR (4, 0);
1921
1922   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1923   aarch64_set_reg_u64 (cpu, rd, NO_SP,
1924                        aarch64_get_reg_u32 (cpu, rn, NO_SP)
1925                        + shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
1926                                     shift, count));
1927 }
1928
1929 /* 64 bit ADD shifted register.  */
1930 static void
1931 add64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
1932 {
1933   unsigned rm = INSTR (20, 16);
1934   unsigned rn = INSTR (9, 5);
1935   unsigned rd = INSTR (4, 0);
1936
1937   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1938   aarch64_set_reg_u64 (cpu, rd, NO_SP,
1939                        aarch64_get_reg_u64 (cpu, rn, NO_SP)
1940                        + shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
1941                                     shift, count));
1942 }
1943
1944 /* 32 bit ADD shifted register setting flags.  */
1945 static void
1946 adds32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
1947 {
1948   unsigned rm = INSTR (20, 16);
1949   unsigned rn = INSTR (9, 5);
1950   unsigned rd = INSTR (4, 0);
1951
1952   uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
1953   uint32_t value2 = shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
1954                                shift, count);
1955
1956   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1957   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
1958   set_flags_for_add32 (cpu, value1, value2);
1959 }
1960
1961 /* 64 bit ADD shifted register setting flags.  */
1962 static void
1963 adds64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
1964 {
1965   unsigned rm = INSTR (20, 16);
1966   unsigned rn = INSTR (9, 5);
1967   unsigned rd = INSTR (4, 0);
1968
1969   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
1970   uint64_t value2 = shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
1971                                shift, count);
1972
1973   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1974   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
1975   set_flags_for_add64 (cpu, value1, value2);
1976 }
1977
1978 /* 32 bit SUB shifted register.  */
1979 static void
1980 sub32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
1981 {
1982   unsigned rm = INSTR (20, 16);
1983   unsigned rn = INSTR (9, 5);
1984   unsigned rd = INSTR (4, 0);
1985
1986   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
1987   aarch64_set_reg_u64 (cpu, rd, NO_SP,
1988                        aarch64_get_reg_u32 (cpu, rn, NO_SP)
1989                        - shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
1990                                     shift, count));
1991 }
1992
1993 /* 64 bit SUB shifted register.  */
1994 static void
1995 sub64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
1996 {
1997   unsigned rm = INSTR (20, 16);
1998   unsigned rn = INSTR (9, 5);
1999   unsigned rd = INSTR (4, 0);
2000
2001   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2002   aarch64_set_reg_u64 (cpu, rd, NO_SP,
2003                        aarch64_get_reg_u64 (cpu, rn, NO_SP)
2004                        - shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
2005                                     shift, count));
2006 }
2007
2008 /* 32 bit SUB shifted register setting flags.  */
2009 static void
2010 subs32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
2011 {
2012   unsigned rm = INSTR (20, 16);
2013   unsigned rn = INSTR (9, 5);
2014   unsigned rd = INSTR (4, 0);
2015
2016   uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
2017   uint32_t value2 = shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
2018                               shift, count);
2019
2020   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2021   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
2022   set_flags_for_sub32 (cpu, value1, value2);
2023 }
2024
2025 /* 64 bit SUB shifted register setting flags.  */
2026 static void
2027 subs64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
2028 {
2029   unsigned rm = INSTR (20, 16);
2030   unsigned rn = INSTR (9, 5);
2031   unsigned rd = INSTR (4, 0);
2032
2033   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
2034   uint64_t value2 = shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
2035                                shift, count);
2036
2037   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2038   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
2039   set_flags_for_sub64 (cpu, value1, value2);
2040 }
2041
2042 /* First a couple more helpers to fetch the
2043    relevant source register element either
2044    sign or zero extended as required by the
2045    extension value.  */
2046
2047 static uint32_t
2048 extreg32 (sim_cpu *cpu, unsigned int lo, Extension extension)
2049 {
2050   switch (extension)
2051     {
2052     case UXTB: return aarch64_get_reg_u8  (cpu, lo, NO_SP);
2053     case UXTH: return aarch64_get_reg_u16 (cpu, lo, NO_SP);
2054     case UXTW: /* Fall through.  */
2055     case UXTX: return aarch64_get_reg_u32 (cpu, lo, NO_SP);
2056     case SXTB: return aarch64_get_reg_s8  (cpu, lo, NO_SP);
2057     case SXTH: return aarch64_get_reg_s16 (cpu, lo, NO_SP);
2058     case SXTW: /* Fall through.  */
2059     case SXTX: /* Fall through.  */
2060     default:   return aarch64_get_reg_s32 (cpu, lo, NO_SP);
2061   }
2062 }
2063
2064 static uint64_t
2065 extreg64 (sim_cpu *cpu, unsigned int lo, Extension extension)
2066 {
2067   switch (extension)
2068     {
2069     case UXTB: return aarch64_get_reg_u8  (cpu, lo, NO_SP);
2070     case UXTH: return aarch64_get_reg_u16 (cpu, lo, NO_SP);
2071     case UXTW: return aarch64_get_reg_u32 (cpu, lo, NO_SP);
2072     case UXTX: return aarch64_get_reg_u64 (cpu, lo, NO_SP);
2073     case SXTB: return aarch64_get_reg_s8  (cpu, lo, NO_SP);
2074     case SXTH: return aarch64_get_reg_s16 (cpu, lo, NO_SP);
2075     case SXTW: return aarch64_get_reg_s32 (cpu, lo, NO_SP);
2076     case SXTX:
2077     default:   return aarch64_get_reg_s64 (cpu, lo, NO_SP);
2078     }
2079 }
2080
2081 /* Arithmetic extending register
2082    These allow an optional sign extension of some portion of the
2083    second source register followed by an optional left shift of
2084    between 1 and 4 bits (i.e. a shift of 0-4 bits???)
2085
2086    N.B output (dest) and first input arg (source) may normally be Xn
2087    or SP. However, for flag setting operations dest can only be
2088    Xn. Second input registers are always Xn.  */
2089
2090 /* 32 bit ADD extending register.  */
2091 static void
2092 add32_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
2093 {
2094   unsigned rm = INSTR (20, 16);
2095   unsigned rn = INSTR (9, 5);
2096   unsigned rd = INSTR (4, 0);
2097
2098   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2099   aarch64_set_reg_u64 (cpu, rd, SP_OK,
2100                        aarch64_get_reg_u32 (cpu, rn, SP_OK)
2101                        + (extreg32 (cpu, rm, extension) << shift));
2102 }
2103
2104 /* 64 bit ADD extending register.
2105    N.B. This subsumes the case with 64 bit source2 and UXTX #n or LSL #0.  */
2106 static void
2107 add64_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
2108 {
2109   unsigned rm = INSTR (20, 16);
2110   unsigned rn = INSTR (9, 5);
2111   unsigned rd = INSTR (4, 0);
2112
2113   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2114   aarch64_set_reg_u64 (cpu, rd, SP_OK,
2115                        aarch64_get_reg_u64 (cpu, rn, SP_OK)
2116                        + (extreg64 (cpu, rm, extension) << shift));
2117 }
2118
2119 /* 32 bit ADD extending register setting flags.  */
2120 static void
2121 adds32_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
2122 {
2123   unsigned rm = INSTR (20, 16);
2124   unsigned rn = INSTR (9, 5);
2125   unsigned rd = INSTR (4, 0);
2126
2127   uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, SP_OK);
2128   uint32_t value2 = extreg32 (cpu, rm, extension) << shift;
2129
2130   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2131   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
2132   set_flags_for_add32 (cpu, value1, value2);
2133 }
2134
2135 /* 64 bit ADD extending register setting flags  */
2136 /* N.B. this subsumes the case with 64 bit source2 and UXTX #n or LSL #0  */
2137 static void
2138 adds64_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
2139 {
2140   unsigned rm = INSTR (20, 16);
2141   unsigned rn = INSTR (9, 5);
2142   unsigned rd = INSTR (4, 0);
2143
2144   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
2145   uint64_t value2 = extreg64 (cpu, rm, extension) << shift;
2146
2147   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2148   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2);
2149   set_flags_for_add64 (cpu, value1, value2);
2150 }
2151
2152 /* 32 bit SUB extending register.  */
2153 static void
2154 sub32_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
2155 {
2156   unsigned rm = INSTR (20, 16);
2157   unsigned rn = INSTR (9, 5);
2158   unsigned rd = INSTR (4, 0);
2159
2160   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2161   aarch64_set_reg_u64 (cpu, rd, SP_OK,
2162                        aarch64_get_reg_u32 (cpu, rn, SP_OK)
2163                        - (extreg32 (cpu, rm, extension) << shift));
2164 }
2165
2166 /* 64 bit SUB extending register.  */
2167 /* N.B. this subsumes the case with 64 bit source2 and UXTX #n or LSL #0.  */
2168 static void
2169 sub64_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
2170 {
2171   unsigned rm = INSTR (20, 16);
2172   unsigned rn = INSTR (9, 5);
2173   unsigned rd = INSTR (4, 0);
2174
2175   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2176   aarch64_set_reg_u64 (cpu, rd, SP_OK,
2177                        aarch64_get_reg_u64 (cpu, rn, SP_OK)
2178                        - (extreg64 (cpu, rm, extension) << shift));
2179 }
2180
2181 /* 32 bit SUB extending register setting flags.  */
2182 static void
2183 subs32_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
2184 {
2185   unsigned rm = INSTR (20, 16);
2186   unsigned rn = INSTR (9, 5);
2187   unsigned rd = INSTR (4, 0);
2188
2189   uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, SP_OK);
2190   uint32_t value2 = extreg32 (cpu, rm, extension) << shift;
2191
2192   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2193   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
2194   set_flags_for_sub32 (cpu, value1, value2);
2195 }
2196
2197 /* 64 bit SUB extending register setting flags  */
2198 /* N.B. this subsumes the case with 64 bit source2 and UXTX #n or LSL #0  */
2199 static void
2200 subs64_ext (sim_cpu *cpu, Extension extension, uint32_t shift)
2201 {
2202   unsigned rm = INSTR (20, 16);
2203   unsigned rn = INSTR (9, 5);
2204   unsigned rd = INSTR (4, 0);
2205
2206   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK);
2207   uint64_t value2 = extreg64 (cpu, rm, extension) << shift;
2208
2209   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2210   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2);
2211   set_flags_for_sub64 (cpu, value1, value2);
2212 }
2213
2214 static void
2215 dexAddSubtractImmediate (sim_cpu *cpu)
2216 {
2217   /* instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
2218      instr[30]    = op : 0 ==> ADD, 1 ==> SUB
2219      instr[29]    = set : 0 ==> no flags, 1 ==> set flags
2220      instr[28,24] = 10001
2221      instr[23,22] = shift : 00 == LSL#0, 01 = LSL#12 1x = UNALLOC
2222      instr[21,10] = uimm12
2223      instr[9,5]   = Rn
2224      instr[4,0]   = Rd  */
2225
2226   /* N.B. the shift is applied at decode before calling the add/sub routine.  */
2227   uint32_t shift = INSTR (23, 22);
2228   uint32_t imm = INSTR (21, 10);
2229   uint32_t dispatch = INSTR (31, 29);
2230
2231   NYI_assert (28, 24, 0x11);
2232
2233   if (shift > 1)
2234     HALT_UNALLOC;
2235
2236   if (shift)
2237     imm <<= 12;
2238
2239   switch (dispatch)
2240     {
2241     case 0: add32 (cpu, imm); break;
2242     case 1: adds32 (cpu, imm); break;
2243     case 2: sub32 (cpu, imm); break;
2244     case 3: subs32 (cpu, imm); break;
2245     case 4: add64 (cpu, imm); break;
2246     case 5: adds64 (cpu, imm); break;
2247     case 6: sub64 (cpu, imm); break;
2248     case 7: subs64 (cpu, imm); break;
2249     }
2250 }
2251
2252 static void
2253 dexAddSubtractShiftedRegister (sim_cpu *cpu)
2254 {
2255   /* instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
2256      instr[30,29] = op : 00 ==> ADD, 01 ==> ADDS, 10 ==> SUB, 11 ==> SUBS
2257      instr[28,24] = 01011
2258      instr[23,22] = shift : 0 ==> LSL, 1 ==> LSR, 2 ==> ASR, 3 ==> UNALLOC
2259      instr[21]    = 0
2260      instr[20,16] = Rm
2261      instr[15,10] = count : must be 0xxxxx for 32 bit
2262      instr[9,5]   = Rn
2263      instr[4,0]   = Rd  */
2264
2265   uint32_t size = INSTR (31, 31);
2266   uint32_t count = INSTR (15, 10);
2267   Shift shiftType = INSTR (23, 22);
2268
2269   NYI_assert (28, 24, 0x0B);
2270   NYI_assert (21, 21, 0);
2271
2272   /* Shift encoded as ROR is unallocated.  */
2273   if (shiftType == ROR)
2274     HALT_UNALLOC;
2275
2276   /* 32 bit operations must have count[5] = 0
2277      or else we have an UNALLOC.  */
2278   if (size == 0 && uimm (count, 5, 5))
2279     HALT_UNALLOC;
2280
2281   /* Dispatch on size:op i.e instr [31,29].  */
2282   switch (INSTR (31, 29))
2283     {
2284     case 0: add32_shift  (cpu, shiftType, count); break;
2285     case 1: adds32_shift (cpu, shiftType, count); break;
2286     case 2: sub32_shift  (cpu, shiftType, count); break;
2287     case 3: subs32_shift (cpu, shiftType, count); break;
2288     case 4: add64_shift  (cpu, shiftType, count); break;
2289     case 5: adds64_shift (cpu, shiftType, count); break;
2290     case 6: sub64_shift  (cpu, shiftType, count); break;
2291     case 7: subs64_shift (cpu, shiftType, count); break;
2292     }
2293 }
2294
2295 static void
2296 dexAddSubtractExtendedRegister (sim_cpu *cpu)
2297 {
2298   /* instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
2299      instr[30]    = op : 0 ==> ADD, 1 ==> SUB
2300      instr[29]    = set? : 0 ==> no flags, 1 ==> set flags
2301      instr[28,24] = 01011
2302      instr[23,22] = opt : 0 ==> ok, 1,2,3 ==> UNALLOC
2303      instr[21]    = 1
2304      instr[20,16] = Rm
2305      instr[15,13] = option : 000 ==> UXTB, 001 ==> UXTH,
2306                              000 ==> LSL|UXTW, 001 ==> UXTZ,
2307                              000 ==> SXTB, 001 ==> SXTH,
2308                              000 ==> SXTW, 001 ==> SXTX,
2309      instr[12,10] = shift : 0,1,2,3,4 ==> ok, 5,6,7 ==> UNALLOC
2310      instr[9,5]   = Rn
2311      instr[4,0]   = Rd  */
2312
2313   Extension extensionType = INSTR (15, 13);
2314   uint32_t shift = INSTR (12, 10);
2315
2316   NYI_assert (28, 24, 0x0B);
2317   NYI_assert (21, 21, 1);
2318
2319   /* Shift may not exceed 4.  */
2320   if (shift > 4)
2321     HALT_UNALLOC;
2322
2323   /* Dispatch on size:op:set?.  */
2324   switch (INSTR (31, 29))
2325     {
2326     case 0: add32_ext  (cpu, extensionType, shift); break;
2327     case 1: adds32_ext (cpu, extensionType, shift); break;
2328     case 2: sub32_ext  (cpu, extensionType, shift); break;
2329     case 3: subs32_ext (cpu, extensionType, shift); break;
2330     case 4: add64_ext  (cpu, extensionType, shift); break;
2331     case 5: adds64_ext (cpu, extensionType, shift); break;
2332     case 6: sub64_ext  (cpu, extensionType, shift); break;
2333     case 7: subs64_ext (cpu, extensionType, shift); break;
2334     }
2335 }
2336
2337 /* Conditional data processing
2338    Condition register is implicit 3rd source.  */
2339
2340 /* 32 bit add with carry.  */
2341 /* N.B register args may not be SP.  */
2342
2343 static void
2344 adc32 (sim_cpu *cpu)
2345 {
2346   unsigned rm = INSTR (20, 16);
2347   unsigned rn = INSTR (9, 5);
2348   unsigned rd = INSTR (4, 0);
2349
2350   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2351   aarch64_set_reg_u64 (cpu, rd, NO_SP,
2352                        aarch64_get_reg_u32 (cpu, rn, NO_SP)
2353                        + aarch64_get_reg_u32 (cpu, rm, NO_SP)
2354                        + IS_SET (C));
2355 }
2356
2357 /* 64 bit add with carry  */
2358 static void
2359 adc64 (sim_cpu *cpu)
2360 {
2361   unsigned rm = INSTR (20, 16);
2362   unsigned rn = INSTR (9, 5);
2363   unsigned rd = INSTR (4, 0);
2364
2365   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2366   aarch64_set_reg_u64 (cpu, rd, NO_SP,
2367                        aarch64_get_reg_u64 (cpu, rn, NO_SP)
2368                        + aarch64_get_reg_u64 (cpu, rm, NO_SP)
2369                        + IS_SET (C));
2370 }
2371
2372 /* 32 bit add with carry setting flags.  */
2373 static void
2374 adcs32 (sim_cpu *cpu)
2375 {
2376   unsigned rm = INSTR (20, 16);
2377   unsigned rn = INSTR (9, 5);
2378   unsigned rd = INSTR (4, 0);
2379
2380   uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
2381   uint32_t value2 = aarch64_get_reg_u32 (cpu, rm, NO_SP);
2382   uint32_t carry = IS_SET (C);
2383
2384   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2385   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2 + carry);
2386   set_flags_for_add32 (cpu, value1, value2 + carry);
2387 }
2388
2389 /* 64 bit add with carry setting flags.  */
2390 static void
2391 adcs64 (sim_cpu *cpu)
2392 {
2393   unsigned rm = INSTR (20, 16);
2394   unsigned rn = INSTR (9, 5);
2395   unsigned rd = INSTR (4, 0);
2396
2397   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
2398   uint64_t value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP);
2399   uint64_t carry = IS_SET (C);
2400
2401   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2402   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2 + carry);
2403   set_flags_for_add64 (cpu, value1, value2 + carry);
2404 }
2405
2406 /* 32 bit sub with carry.  */
2407 static void
2408 sbc32 (sim_cpu *cpu)
2409 {
2410   unsigned rm = INSTR (20, 16);
2411   unsigned rn = INSTR (9, 5); /* ngc iff rn == 31.  */
2412   unsigned rd = INSTR (4, 0);
2413
2414   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2415   aarch64_set_reg_u64 (cpu, rd, NO_SP,
2416                        aarch64_get_reg_u32 (cpu, rn, NO_SP)
2417                        - aarch64_get_reg_u32 (cpu, rm, NO_SP)
2418                        - 1 + IS_SET (C));
2419 }
2420
2421 /* 64 bit sub with carry  */
2422 static void
2423 sbc64 (sim_cpu *cpu)
2424 {
2425   unsigned rm = INSTR (20, 16);
2426   unsigned rn = INSTR (9, 5);
2427   unsigned rd = INSTR (4, 0);
2428
2429   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2430   aarch64_set_reg_u64 (cpu, rd, NO_SP,
2431                        aarch64_get_reg_u64 (cpu, rn, NO_SP)
2432                        - aarch64_get_reg_u64 (cpu, rm, NO_SP)
2433                        - 1 + IS_SET (C));
2434 }
2435
2436 /* 32 bit sub with carry setting flags  */
2437 static void
2438 sbcs32 (sim_cpu *cpu)
2439 {
2440   unsigned rm = INSTR (20, 16);
2441   unsigned rn = INSTR (9, 5);
2442   unsigned rd = INSTR (4, 0);
2443
2444   uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
2445   uint32_t value2 = aarch64_get_reg_u32 (cpu, rm, NO_SP);
2446   uint32_t carry  = IS_SET (C);
2447   uint32_t result = value1 - value2 + 1 - carry;
2448
2449   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2450   aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
2451   set_flags_for_sub32 (cpu, value1, value2 + 1 - carry);
2452 }
2453
2454 /* 64 bit sub with carry setting flags  */
2455 static void
2456 sbcs64 (sim_cpu *cpu)
2457 {
2458   unsigned rm = INSTR (20, 16);
2459   unsigned rn = INSTR (9, 5);
2460   unsigned rd = INSTR (4, 0);
2461
2462   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
2463   uint64_t value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP);
2464   uint64_t carry  = IS_SET (C);
2465   uint64_t result = value1 - value2 + 1 - carry;
2466
2467   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2468   aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
2469   set_flags_for_sub64 (cpu, value1, value2 + 1 - carry);
2470 }
2471
2472 static void
2473 dexAddSubtractWithCarry (sim_cpu *cpu)
2474 {
2475   /* instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
2476      instr[30]    = op : 0 ==> ADC, 1 ==> SBC
2477      instr[29]    = set? : 0 ==> no flags, 1 ==> set flags
2478      instr[28,21] = 1 1010 000
2479      instr[20,16] = Rm
2480      instr[15,10] = op2 : 00000 ==> ok, ow ==> UNALLOC
2481      instr[9,5]   = Rn
2482      instr[4,0]   = Rd  */
2483
2484   uint32_t op2 = INSTR (15, 10);
2485
2486   NYI_assert (28, 21, 0xD0);
2487
2488   if (op2 != 0)
2489     HALT_UNALLOC;
2490
2491   /* Dispatch on size:op:set?.  */
2492   switch (INSTR (31, 29))
2493     {
2494     case 0: adc32 (cpu); break;
2495     case 1: adcs32 (cpu); break;
2496     case 2: sbc32 (cpu); break;
2497     case 3: sbcs32 (cpu); break;
2498     case 4: adc64 (cpu); break;
2499     case 5: adcs64 (cpu); break;
2500     case 6: sbc64 (cpu); break;
2501     case 7: sbcs64 (cpu); break;
2502     }
2503 }
2504
2505 static uint32_t
2506 testConditionCode (sim_cpu *cpu, CondCode cc)
2507 {
2508   /* This should be reduceable to branchless logic
2509      by some careful testing of bits in CC followed
2510      by the requisite masking and combining of bits
2511      from the flag register.
2512
2513      For now we do it with a switch.  */
2514   int res;
2515
2516   switch (cc)
2517     {
2518     case EQ:  res = IS_SET (Z);    break;
2519     case NE:  res = IS_CLEAR (Z);  break;
2520     case CS:  res = IS_SET (C);    break;
2521     case CC:  res = IS_CLEAR (C);  break;
2522     case MI:  res = IS_SET (N);    break;
2523     case PL:  res = IS_CLEAR (N);  break;
2524     case VS:  res = IS_SET (V);    break;
2525     case VC:  res = IS_CLEAR (V);  break;
2526     case HI:  res = IS_SET (C) && IS_CLEAR (Z);  break;
2527     case LS:  res = IS_CLEAR (C) || IS_SET (Z);  break;
2528     case GE:  res = IS_SET (N) == IS_SET (V);    break;
2529     case LT:  res = IS_SET (N) != IS_SET (V);    break;
2530     case GT:  res = IS_CLEAR (Z) && (IS_SET (N) == IS_SET (V));  break;
2531     case LE:  res = IS_SET (Z) || (IS_SET (N) != IS_SET (V));    break;
2532     case AL:
2533     case NV:
2534     default:
2535       res = 1;
2536       break;
2537     }
2538   return res;
2539 }
2540
2541 static void
2542 CondCompare (sim_cpu *cpu) /* aka: ccmp and ccmn  */
2543 {
2544   /* instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
2545      instr[30]    = compare with positive (1) or negative value (0)
2546      instr[29,21] = 1 1101 0010
2547      instr[20,16] = Rm or const
2548      instr[15,12] = cond
2549      instr[11]    = compare reg (0) or const (1)
2550      instr[10]    = 0
2551      instr[9,5]   = Rn
2552      instr[4]     = 0
2553      instr[3,0]   = value for CPSR bits if the comparison does not take place.  */
2554   signed int negate;
2555   unsigned rm;
2556   unsigned rn;
2557
2558   NYI_assert (29, 21, 0x1d2);
2559   NYI_assert (10, 10, 0);
2560   NYI_assert (4, 4, 0);
2561
2562   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2563   if (! testConditionCode (cpu, INSTR (15, 12)))
2564     {
2565       aarch64_set_CPSR (cpu, INSTR (3, 0));
2566       return;
2567     }
2568
2569   negate = INSTR (30, 30) ? 1 : -1;
2570   rm = INSTR (20, 16);
2571   rn = INSTR ( 9,  5);
2572
2573   if (INSTR (31, 31))
2574     {
2575       if (INSTR (11, 11))
2576         set_flags_for_sub64 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK),
2577                              negate * (uint64_t) rm);
2578       else
2579         set_flags_for_sub64 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK),
2580                              negate * aarch64_get_reg_u64 (cpu, rm, SP_OK));
2581     }
2582   else
2583     {
2584       if (INSTR (11, 11))
2585         set_flags_for_sub32 (cpu, aarch64_get_reg_u32 (cpu, rn, SP_OK),
2586                              negate * rm);
2587       else
2588         set_flags_for_sub32 (cpu, aarch64_get_reg_u32 (cpu, rn, SP_OK),
2589                              negate * aarch64_get_reg_u32 (cpu, rm, SP_OK));
2590     }
2591 }
2592
2593 static void
2594 do_vec_MOV_whole_vector (sim_cpu *cpu)
2595 {
2596   /* MOV Vd.T, Vs.T  (alias for ORR Vd.T, Vn.T, Vm.T where Vn == Vm)
2597
2598      instr[31]    = 0
2599      instr[30]    = half(0)/full(1)
2600      instr[29,21] = 001110101
2601      instr[20,16] = Vs
2602      instr[15,10] = 000111
2603      instr[9,5]   = Vs
2604      instr[4,0]   = Vd  */
2605
2606   unsigned vs = INSTR (9, 5);
2607   unsigned vd = INSTR (4, 0);
2608
2609   NYI_assert (29, 21, 0x075);
2610   NYI_assert (15, 10, 0x07);
2611
2612   if (INSTR (20, 16) != vs)
2613     HALT_NYI;
2614
2615   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2616   if (INSTR (30, 30))
2617     aarch64_set_vec_u64 (cpu, vd, 1, aarch64_get_vec_u64 (cpu, vs, 1));
2618
2619   aarch64_set_vec_u64 (cpu, vd, 0, aarch64_get_vec_u64 (cpu, vs, 0));
2620 }
2621
2622 static void
2623 do_vec_MOV_into_scalar (sim_cpu *cpu)
2624 {
2625   /* instr[31]    = 0
2626      instr[30]    = word(0)/long(1)
2627      instr[29,21] = 00 1110 000
2628      instr[20,18] = element size and index
2629      instr[17,10] = 00 0011 11
2630      instr[9,5]   = V source
2631      instr[4,0]   = R dest  */
2632
2633   unsigned vs = INSTR (9, 5);
2634   unsigned rd = INSTR (4, 0);
2635
2636   NYI_assert (29, 21, 0x070);
2637   NYI_assert (17, 10, 0x0F);
2638
2639   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2640   switch (INSTR (20, 18))
2641     {
2642     case 0x2:
2643       aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u64 (cpu, vs, 0));
2644       break;
2645
2646     case 0x6:
2647       aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u64 (cpu, vs, 1));
2648       break;
2649
2650     case 0x1:
2651     case 0x3:
2652     case 0x5:
2653     case 0x7:
2654       aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u32
2655                            (cpu, vs, INSTR (20, 19)));
2656       break;
2657
2658     default:
2659       HALT_NYI;
2660     }
2661 }
2662
2663 static void
2664 do_vec_INS (sim_cpu *cpu)
2665 {
2666   /* instr[31,21] = 01001110000
2667      instr[20,16] = element size and index
2668      instr[15,10] = 000111
2669      instr[9,5]   = W source
2670      instr[4,0]   = V dest  */
2671
2672   int index;
2673   unsigned rs = INSTR (9, 5);
2674   unsigned vd = INSTR (4, 0);
2675
2676   NYI_assert (31, 21, 0x270);
2677   NYI_assert (15, 10, 0x07);
2678
2679   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2680   if (INSTR (16, 16))
2681     {
2682       index = INSTR (20, 17);
2683       aarch64_set_vec_u8 (cpu, vd, index,
2684                           aarch64_get_reg_u8 (cpu, rs, NO_SP));
2685     }
2686   else if (INSTR (17, 17))
2687     {
2688       index = INSTR (20, 18);
2689       aarch64_set_vec_u16 (cpu, vd, index,
2690                            aarch64_get_reg_u16 (cpu, rs, NO_SP));
2691     }
2692   else if (INSTR (18, 18))
2693     {
2694       index = INSTR (20, 19);
2695       aarch64_set_vec_u32 (cpu, vd, index,
2696                            aarch64_get_reg_u32 (cpu, rs, NO_SP));
2697     }
2698   else if (INSTR (19, 19))
2699     {
2700       index = INSTR (20, 20);
2701       aarch64_set_vec_u64 (cpu, vd, index,
2702                            aarch64_get_reg_u64 (cpu, rs, NO_SP));
2703     }
2704   else
2705     HALT_NYI;
2706 }
2707
2708 static void
2709 do_vec_DUP_vector_into_vector (sim_cpu *cpu)
2710 {
2711   /* instr[31]    = 0
2712      instr[30]    = half(0)/full(1)
2713      instr[29,21] = 00 1110 000
2714      instr[20,16] = element size and index
2715      instr[15,10] = 0000 01
2716      instr[9,5]   = V source
2717      instr[4,0]   = V dest.  */
2718
2719   unsigned full = INSTR (30, 30);
2720   unsigned vs = INSTR (9, 5);
2721   unsigned vd = INSTR (4, 0);
2722   int i, index;
2723
2724   NYI_assert (29, 21, 0x070);
2725   NYI_assert (15, 10, 0x01);
2726
2727   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2728   if (INSTR (16, 16))
2729     {
2730       index = INSTR (20, 17);
2731
2732       for (i = 0; i < (full ? 16 : 8); i++)
2733         aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vs, index));
2734     }
2735   else if (INSTR (17, 17))
2736     {
2737       index = INSTR (20, 18);
2738
2739       for (i = 0; i < (full ? 8 : 4); i++)
2740         aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vs, index));
2741     }
2742   else if (INSTR (18, 18))
2743     {
2744       index = INSTR (20, 19);
2745
2746       for (i = 0; i < (full ? 4 : 2); i++)
2747         aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vs, index));
2748     }
2749   else
2750     {
2751       if (INSTR (19, 19) == 0)
2752         HALT_UNALLOC;
2753
2754       if (! full)
2755         HALT_UNALLOC;
2756
2757       index = INSTR (20, 20);
2758
2759       for (i = 0; i < 2; i++)
2760         aarch64_set_vec_u64 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vs, index));
2761     }
2762 }
2763
2764 static void
2765 do_vec_TBL (sim_cpu *cpu)
2766 {
2767   /* instr[31]    = 0
2768      instr[30]    = half(0)/full(1)
2769      instr[29,21] = 00 1110 000
2770      instr[20,16] = Vm
2771      instr[15]    = 0
2772      instr[14,13] = vec length
2773      instr[12,10] = 000
2774      instr[9,5]   = V start
2775      instr[4,0]   = V dest  */
2776
2777   int full    = INSTR (30, 30);
2778   int len     = INSTR (14, 13) + 1;
2779   unsigned vm = INSTR (20, 16);
2780   unsigned vn = INSTR (9, 5);
2781   unsigned vd = INSTR (4, 0);
2782   unsigned i;
2783
2784   NYI_assert (29, 21, 0x070);
2785   NYI_assert (12, 10, 0);
2786
2787   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2788   for (i = 0; i < (full ? 16 : 8); i++)
2789     {
2790       unsigned int selector = aarch64_get_vec_u8 (cpu, vm, i);
2791       uint8_t val;
2792
2793       if (selector < 16)
2794         val = aarch64_get_vec_u8 (cpu, vn, selector);
2795       else if (selector < 32)
2796         val = len < 2 ? 0 : aarch64_get_vec_u8 (cpu, vn + 1, selector - 16);
2797       else if (selector < 48)
2798         val = len < 3 ? 0 : aarch64_get_vec_u8 (cpu, vn + 2, selector - 32);
2799       else if (selector < 64)
2800         val = len < 4 ? 0 : aarch64_get_vec_u8 (cpu, vn + 3, selector - 48);
2801       else
2802         val = 0;
2803
2804       aarch64_set_vec_u8 (cpu, vd, i, val);
2805     }
2806 }
2807
2808 static void
2809 do_vec_TRN (sim_cpu *cpu)
2810 {
2811   /* instr[31]    = 0
2812      instr[30]    = half(0)/full(1)
2813      instr[29,24] = 00 1110
2814      instr[23,22] = size
2815      instr[21]    = 0
2816      instr[20,16] = Vm
2817      instr[15]    = 0
2818      instr[14]    = TRN1 (0) / TRN2 (1)
2819      instr[13,10] = 1010
2820      instr[9,5]   = V source
2821      instr[4,0]   = V dest.  */
2822
2823   int full    = INSTR (30, 30);
2824   int second  = INSTR (14, 14);
2825   unsigned vm = INSTR (20, 16);
2826   unsigned vn = INSTR (9, 5);
2827   unsigned vd = INSTR (4, 0);
2828   unsigned i;
2829
2830   NYI_assert (29, 24, 0x0E);
2831   NYI_assert (13, 10, 0xA);
2832
2833   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2834   switch (INSTR (23, 22))
2835     {
2836     case 0:
2837       for (i = 0; i < (full ? 8 : 4); i++)
2838         {
2839           aarch64_set_vec_u8
2840             (cpu, vd, i * 2,
2841              aarch64_get_vec_u8 (cpu, second ? vm : vn, i * 2));
2842           aarch64_set_vec_u8
2843             (cpu, vd, 1 * 2 + 1,
2844              aarch64_get_vec_u8 (cpu, second ? vn : vm, i * 2 + 1));
2845         }
2846       break;
2847
2848     case 1:
2849       for (i = 0; i < (full ? 4 : 2); i++)
2850         {
2851           aarch64_set_vec_u16
2852             (cpu, vd, i * 2,
2853              aarch64_get_vec_u16 (cpu, second ? vm : vn, i * 2));
2854           aarch64_set_vec_u16
2855             (cpu, vd, 1 * 2 + 1,
2856              aarch64_get_vec_u16 (cpu, second ? vn : vm, i * 2 + 1));
2857         }
2858       break;
2859
2860     case 2:
2861       aarch64_set_vec_u32
2862         (cpu, vd, 0, aarch64_get_vec_u32 (cpu, second ? vm : vn, 0));
2863       aarch64_set_vec_u32
2864         (cpu, vd, 1, aarch64_get_vec_u32 (cpu, second ? vn : vm, 1));
2865       aarch64_set_vec_u32
2866         (cpu, vd, 2, aarch64_get_vec_u32 (cpu, second ? vm : vn, 2));
2867       aarch64_set_vec_u32
2868         (cpu, vd, 3, aarch64_get_vec_u32 (cpu, second ? vn : vm, 3));
2869       break;
2870
2871     case 3:
2872       if (! full)
2873         HALT_UNALLOC;
2874
2875       aarch64_set_vec_u64 (cpu, vd, 0,
2876                            aarch64_get_vec_u64 (cpu, second ? vm : vn, 0));
2877       aarch64_set_vec_u64 (cpu, vd, 1,
2878                            aarch64_get_vec_u64 (cpu, second ? vn : vm, 1));
2879       break;
2880     }
2881 }
2882
2883 static void
2884 do_vec_DUP_scalar_into_vector (sim_cpu *cpu)
2885 {
2886   /* instr[31]    = 0
2887      instr[30]    = 0=> zero top 64-bits, 1=> duplicate into top 64-bits
2888                     [must be 1 for 64-bit xfer]
2889      instr[29,20] = 00 1110 0000
2890      instr[19,16] = element size: 0001=> 8-bits, 0010=> 16-bits,
2891                                   0100=> 32-bits. 1000=>64-bits
2892      instr[15,10] = 0000 11
2893      instr[9,5]   = W source
2894      instr[4,0]   = V dest.  */
2895
2896   unsigned i;
2897   unsigned Vd = INSTR (4, 0);
2898   unsigned Rs = INSTR (9, 5);
2899   int both    = INSTR (30, 30);
2900
2901   NYI_assert (29, 20, 0x0E0);
2902   NYI_assert (15, 10, 0x03);
2903
2904   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2905   switch (INSTR (19, 16))
2906     {
2907     case 1:
2908       for (i = 0; i < (both ? 16 : 8); i++)
2909         aarch64_set_vec_u8 (cpu, Vd, i, aarch64_get_reg_u8 (cpu, Rs, NO_SP));
2910       break;
2911
2912     case 2:
2913       for (i = 0; i < (both ? 8 : 4); i++)
2914         aarch64_set_vec_u16 (cpu, Vd, i, aarch64_get_reg_u16 (cpu, Rs, NO_SP));
2915       break;
2916
2917     case 4:
2918       for (i = 0; i < (both ? 4 : 2); i++)
2919         aarch64_set_vec_u32 (cpu, Vd, i, aarch64_get_reg_u32 (cpu, Rs, NO_SP));
2920       break;
2921
2922     case 8:
2923       if (!both)
2924         HALT_NYI;
2925       aarch64_set_vec_u64 (cpu, Vd, 0, aarch64_get_reg_u64 (cpu, Rs, NO_SP));
2926       aarch64_set_vec_u64 (cpu, Vd, 1, aarch64_get_reg_u64 (cpu, Rs, NO_SP));
2927       break;
2928
2929     default:
2930       HALT_NYI;
2931     }
2932 }
2933
2934 static void
2935 do_vec_UZP (sim_cpu *cpu)
2936 {
2937   /* instr[31]    = 0
2938      instr[30]    = half(0)/full(1)
2939      instr[29,24] = 00 1110
2940      instr[23,22] = size: byte(00), half(01), word (10), long (11)
2941      instr[21]    = 0
2942      instr[20,16] = Vm
2943      instr[15]    = 0
2944      instr[14]    = lower (0) / upper (1)
2945      instr[13,10] = 0110
2946      instr[9,5]   = Vn
2947      instr[4,0]   = Vd.  */
2948
2949   int full = INSTR (30, 30);
2950   int upper = INSTR (14, 14);
2951
2952   unsigned vm = INSTR (20, 16);
2953   unsigned vn = INSTR (9, 5);
2954   unsigned vd = INSTR (4, 0);
2955
2956   uint64_t val_m1 = aarch64_get_vec_u64 (cpu, vm, 0);
2957   uint64_t val_m2 = aarch64_get_vec_u64 (cpu, vm, 1);
2958   uint64_t val_n1 = aarch64_get_vec_u64 (cpu, vn, 0);
2959   uint64_t val_n2 = aarch64_get_vec_u64 (cpu, vn, 1);
2960
2961   uint64_t val1 = 0;
2962   uint64_t val2 = 0;
2963
2964   uint64_t input1 = upper ? val_n1 : val_m1;
2965   uint64_t input2 = upper ? val_n2 : val_m2;
2966   unsigned i;
2967
2968   NYI_assert (29, 24, 0x0E);
2969   NYI_assert (21, 21, 0);
2970   NYI_assert (15, 15, 0);
2971   NYI_assert (13, 10, 6);
2972
2973   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
2974   switch (INSTR (23, 23))
2975     {
2976     case 0:
2977       for (i = 0; i < 8; i++)
2978         {
2979           val1 |= (input1 >> (i * 8)) & (0xFFULL << (i * 8));
2980           val2 |= (input2 >> (i * 8)) & (0xFFULL << (i * 8));
2981         }
2982       break;
2983
2984     case 1:
2985       for (i = 0; i < 4; i++)
2986         {
2987           val1 |= (input1 >> (i * 16)) & (0xFFFFULL << (i * 16));
2988           val2 |= (input2 >> (i * 16)) & (0xFFFFULL << (i * 16));
2989         }
2990       break;
2991
2992     case 2:
2993       val1 = ((input1 & 0xFFFFFFFF) | ((input1 >> 32) & 0xFFFFFFFF00000000ULL));
2994       val2 = ((input2 & 0xFFFFFFFF) | ((input2 >> 32) & 0xFFFFFFFF00000000ULL));
2995
2996     case 3:
2997       val1 = input1;
2998       val2 = input2;
2999            break;
3000     }
3001
3002   aarch64_set_vec_u64 (cpu, vd, 0, val1);
3003   if (full)
3004     aarch64_set_vec_u64 (cpu, vd, 1, val2);
3005 }
3006
3007 static void
3008 do_vec_ZIP (sim_cpu *cpu)
3009 {
3010   /* instr[31]    = 0
3011      instr[30]    = half(0)/full(1)
3012      instr[29,24] = 00 1110
3013      instr[23,22] = size: byte(00), hald(01), word (10), long (11)
3014      instr[21]    = 0
3015      instr[20,16] = Vm
3016      instr[15]    = 0
3017      instr[14]    = lower (0) / upper (1)
3018      instr[13,10] = 1110
3019      instr[9,5]   = Vn
3020      instr[4,0]   = Vd.  */
3021
3022   int full = INSTR (30, 30);
3023   int upper = INSTR (14, 14);
3024
3025   unsigned vm = INSTR (20, 16);
3026   unsigned vn = INSTR (9, 5);
3027   unsigned vd = INSTR (4, 0);
3028
3029   uint64_t val_m1 = aarch64_get_vec_u64 (cpu, vm, 0);
3030   uint64_t val_m2 = aarch64_get_vec_u64 (cpu, vm, 1);
3031   uint64_t val_n1 = aarch64_get_vec_u64 (cpu, vn, 0);
3032   uint64_t val_n2 = aarch64_get_vec_u64 (cpu, vn, 1);
3033
3034   uint64_t val1 = 0;
3035   uint64_t val2 = 0;
3036
3037   uint64_t input1 = upper ? val_n1 : val_m1;
3038   uint64_t input2 = upper ? val_n2 : val_m2;
3039
3040   NYI_assert (29, 24, 0x0E);
3041   NYI_assert (21, 21, 0);
3042   NYI_assert (15, 15, 0);
3043   NYI_assert (13, 10, 0xE);
3044
3045   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3046   switch (INSTR (23, 23))
3047     {
3048     case 0:
3049       val1 =
3050           ((input1 <<  0) & (0xFF    <<  0))
3051         | ((input2 <<  8) & (0xFF    <<  8))
3052         | ((input1 <<  8) & (0xFF    << 16))
3053         | ((input2 << 16) & (0xFF    << 24))
3054         | ((input1 << 16) & (0xFFULL << 32))
3055         | ((input2 << 24) & (0xFFULL << 40))
3056         | ((input1 << 24) & (0xFFULL << 48))
3057         | ((input2 << 32) & (0xFFULL << 56));
3058
3059       val2 =
3060           ((input1 >> 32) & (0xFF    <<  0))
3061         | ((input2 >> 24) & (0xFF    <<  8))
3062         | ((input1 >> 24) & (0xFF    << 16))
3063         | ((input2 >> 16) & (0xFF    << 24))
3064         | ((input1 >> 16) & (0xFFULL << 32))
3065         | ((input2 >>  8) & (0xFFULL << 40))
3066         | ((input1 >>  8) & (0xFFULL << 48))
3067         | ((input2 >>  0) & (0xFFULL << 56));
3068       break;
3069
3070     case 1:
3071       val1 =
3072           ((input1 <<  0) & (0xFFFF    <<  0))
3073         | ((input2 << 16) & (0xFFFF    << 16))
3074         | ((input1 << 16) & (0xFFFFULL << 32))
3075         | ((input2 << 32) & (0xFFFFULL << 48));
3076
3077       val2 =
3078           ((input1 >> 32) & (0xFFFF    <<  0))
3079         | ((input2 >> 16) & (0xFFFF    << 16))
3080         | ((input1 >> 16) & (0xFFFFULL << 32))
3081         | ((input2 >>  0) & (0xFFFFULL << 48));
3082       break;
3083
3084     case 2:
3085       val1 = (input1 & 0xFFFFFFFFULL) | (input2 << 32);
3086       val2 = (input2 & 0xFFFFFFFFULL) | (input1 << 32);
3087       break;
3088
3089     case 3:
3090       val1 = input1;
3091       val2 = input2;
3092       break;
3093     }
3094
3095   aarch64_set_vec_u64 (cpu, vd, 0, val1);
3096   if (full)
3097     aarch64_set_vec_u64 (cpu, vd, 1, val2);
3098 }
3099
3100 /* Floating point immediates are encoded in 8 bits.
3101    fpimm[7] = sign bit.
3102    fpimm[6:4] = signed exponent.
3103    fpimm[3:0] = fraction (assuming leading 1).
3104    i.e. F = s * 1.f * 2^(e - b).  */
3105
3106 static float
3107 fp_immediate_for_encoding_32 (uint32_t imm8)
3108 {
3109   float u;
3110   uint32_t s, e, f, i;
3111
3112   s = (imm8 >> 7) & 0x1;
3113   e = (imm8 >> 4) & 0x7;
3114   f = imm8 & 0xf;
3115
3116   /* The fp value is s * n/16 * 2r where n is 16+e.  */
3117   u = (16.0 + f) / 16.0;
3118
3119   /* N.B. exponent is signed.  */
3120   if (e < 4)
3121     {
3122       int epos = e;
3123
3124       for (i = 0; i <= epos; i++)
3125         u *= 2.0;
3126     }
3127   else
3128     {
3129       int eneg = 7 - e;
3130
3131       for (i = 0; i < eneg; i++)
3132         u /= 2.0;
3133     }
3134
3135   if (s)
3136     u = - u;
3137
3138   return u;
3139 }
3140
3141 static double
3142 fp_immediate_for_encoding_64 (uint32_t imm8)
3143 {
3144   double u;
3145   uint32_t s, e, f, i;
3146
3147   s = (imm8 >> 7) & 0x1;
3148   e = (imm8 >> 4) & 0x7;
3149   f = imm8 & 0xf;
3150
3151   /* The fp value is s * n/16 * 2r where n is 16+e.  */
3152   u = (16.0 + f) / 16.0;
3153
3154   /* N.B. exponent is signed.  */
3155   if (e < 4)
3156     {
3157       int epos = e;
3158
3159       for (i = 0; i <= epos; i++)
3160         u *= 2.0;
3161     }
3162   else
3163     {
3164       int eneg = 7 - e;
3165
3166       for (i = 0; i < eneg; i++)
3167         u /= 2.0;
3168     }
3169
3170   if (s)
3171     u = - u;
3172
3173   return u;
3174 }
3175
3176 static void
3177 do_vec_MOV_immediate (sim_cpu *cpu)
3178 {
3179   /* instr[31]    = 0
3180      instr[30]    = full/half selector
3181      instr[29,19] = 00111100000
3182      instr[18,16] = high 3 bits of uimm8
3183      instr[15,12] = size & shift:
3184                                   0000 => 32-bit
3185                                   0010 => 32-bit + LSL#8
3186                                   0100 => 32-bit + LSL#16
3187                                   0110 => 32-bit + LSL#24
3188                                   1010 => 16-bit + LSL#8
3189                                   1000 => 16-bit
3190                                   1101 => 32-bit + MSL#16
3191                                   1100 => 32-bit + MSL#8
3192                                   1110 => 8-bit
3193                                   1111 => double
3194      instr[11,10] = 01
3195      instr[9,5]   = low 5-bits of uimm8
3196      instr[4,0]   = Vd.  */
3197
3198   int full     = INSTR (30, 30);
3199   unsigned vd  = INSTR (4, 0);
3200   unsigned val = (INSTR (18, 16) << 5) | INSTR (9, 5);
3201   unsigned i;
3202
3203   NYI_assert (29, 19, 0x1E0);
3204   NYI_assert (11, 10, 1);
3205
3206   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3207   switch (INSTR (15, 12))
3208     {
3209     case 0x0: /* 32-bit, no shift.  */
3210     case 0x2: /* 32-bit, shift by 8.  */
3211     case 0x4: /* 32-bit, shift by 16.  */
3212     case 0x6: /* 32-bit, shift by 24.  */
3213       val <<= (8 * INSTR (14, 13));
3214       for (i = 0; i < (full ? 4 : 2); i++)
3215         aarch64_set_vec_u32 (cpu, vd, i, val);
3216       break;
3217
3218     case 0xa: /* 16-bit, shift by 8.  */
3219       val <<= 8;
3220       /* Fall through.  */
3221     case 0x8: /* 16-bit, no shift.  */
3222       for (i = 0; i < (full ? 8 : 4); i++)
3223         aarch64_set_vec_u16 (cpu, vd, i, val);
3224       /* Fall through.  */
3225     case 0xd: /* 32-bit, mask shift by 16.  */
3226       val <<= 8;
3227       val |= 0xFF;
3228       /* Fall through.  */
3229     case 0xc: /* 32-bit, mask shift by 8. */
3230       val <<= 8;
3231       val |= 0xFF;
3232       for (i = 0; i < (full ? 4 : 2); i++)
3233         aarch64_set_vec_u32 (cpu, vd, i, val);
3234       break;
3235
3236     case 0xe: /* 8-bit, no shift.  */
3237       for (i = 0; i < (full ? 16 : 8); i++)
3238         aarch64_set_vec_u8 (cpu, vd, i, val);
3239       break;
3240
3241     case 0xf: /* FMOV Vs.{2|4}S, #fpimm.  */
3242       {
3243         float u = fp_immediate_for_encoding_32 (val);
3244         for (i = 0; i < (full ? 4 : 2); i++)
3245           aarch64_set_vec_float (cpu, vd, i, u);
3246         break;
3247       }
3248
3249     default:
3250       HALT_NYI;
3251     }
3252 }
3253
3254 static void
3255 do_vec_MVNI (sim_cpu *cpu)
3256 {
3257   /* instr[31]    = 0
3258      instr[30]    = full/half selector
3259      instr[29,19] = 10111100000
3260      instr[18,16] = high 3 bits of uimm8
3261      instr[15,12] = selector
3262      instr[11,10] = 01
3263      instr[9,5]   = low 5-bits of uimm8
3264      instr[4,0]   = Vd.  */
3265
3266   int full     = INSTR (30, 30);
3267   unsigned vd  = INSTR (4, 0);
3268   unsigned val = (INSTR (18, 16) << 5) | INSTR (9, 5);
3269   unsigned i;
3270
3271   NYI_assert (29, 19, 0x5E0);
3272   NYI_assert (11, 10, 1);
3273
3274   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3275   switch (INSTR (15, 12))
3276     {
3277     case 0x0: /* 32-bit, no shift.  */
3278     case 0x2: /* 32-bit, shift by 8.  */
3279     case 0x4: /* 32-bit, shift by 16.  */
3280     case 0x6: /* 32-bit, shift by 24.  */
3281       val <<= (8 * INSTR (14, 13));
3282       val = ~ val;
3283       for (i = 0; i < (full ? 4 : 2); i++)
3284         aarch64_set_vec_u32 (cpu, vd, i, val);
3285       return;
3286
3287     case 0xa: /* 16-bit, 8 bit shift. */
3288       val <<= 8;
3289     case 0x8: /* 16-bit, no shift. */
3290       val = ~ val;
3291       for (i = 0; i < (full ? 8 : 4); i++)
3292         aarch64_set_vec_u16 (cpu, vd, i, val);
3293       return;
3294
3295     case 0xd: /* 32-bit, mask shift by 16.  */
3296       val <<= 8;
3297       val |= 0xFF;
3298     case 0xc: /* 32-bit, mask shift by 8. */
3299       val <<= 8;
3300       val |= 0xFF;
3301       val = ~ val;
3302       for (i = 0; i < (full ? 4 : 2); i++)
3303         aarch64_set_vec_u32 (cpu, vd, i, val);
3304       return;
3305
3306     case 0xE: /* MOVI Dn, #mask64 */
3307       {
3308         uint64_t mask = 0;
3309
3310         for (i = 0; i < 8; i++)
3311           if (val & (1 << i))
3312             mask |= (0xFFUL << (i * 8));
3313         aarch64_set_vec_u64 (cpu, vd, 0, mask);
3314         aarch64_set_vec_u64 (cpu, vd, 1, mask);
3315         return;
3316       }
3317
3318     case 0xf: /* FMOV Vd.2D, #fpimm.  */
3319       {
3320         double u = fp_immediate_for_encoding_64 (val);
3321
3322         if (! full)
3323           HALT_UNALLOC;
3324
3325         aarch64_set_vec_double (cpu, vd, 0, u);
3326         aarch64_set_vec_double (cpu, vd, 1, u);
3327         return;
3328       }
3329
3330     default:
3331       HALT_NYI;
3332     }
3333 }
3334
3335 #define ABS(A) ((A) < 0 ? - (A) : (A))
3336
3337 static void
3338 do_vec_ABS (sim_cpu *cpu)
3339 {
3340   /* instr[31]    = 0
3341      instr[30]    = half(0)/full(1)
3342      instr[29,24] = 00 1110
3343      instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit, 11=> 64-bit
3344      instr[21,10] = 10 0000 1011 10
3345      instr[9,5]   = Vn
3346      instr[4.0]   = Vd.  */
3347
3348   unsigned vn = INSTR (9, 5);
3349   unsigned vd = INSTR (4, 0);
3350   unsigned full = INSTR (30, 30);
3351   unsigned i;
3352
3353   NYI_assert (29, 24, 0x0E);
3354   NYI_assert (21, 10, 0x82E);
3355
3356   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3357   switch (INSTR (23, 22))
3358     {
3359     case 0:
3360       for (i = 0; i < (full ? 16 : 8); i++)
3361         aarch64_set_vec_s8 (cpu, vd, i,
3362                             ABS (aarch64_get_vec_s8 (cpu, vn, i)));
3363       break;
3364
3365     case 1:
3366       for (i = 0; i < (full ? 8 : 4); i++)
3367         aarch64_set_vec_s16 (cpu, vd, i,
3368                              ABS (aarch64_get_vec_s16 (cpu, vn, i)));
3369       break;
3370
3371     case 2:
3372       for (i = 0; i < (full ? 4 : 2); i++)
3373         aarch64_set_vec_s32 (cpu, vd, i,
3374                              ABS (aarch64_get_vec_s32 (cpu, vn, i)));
3375       break;
3376
3377     case 3:
3378       if (! full)
3379         HALT_NYI;
3380       for (i = 0; i < 2; i++)
3381         aarch64_set_vec_s64 (cpu, vd, i,
3382                              ABS (aarch64_get_vec_s64 (cpu, vn, i)));
3383       break;
3384     }
3385 }
3386
3387 static void
3388 do_vec_ADDV (sim_cpu *cpu)
3389 {
3390   /* instr[31]    = 0
3391      instr[30]    = full/half selector
3392      instr[29,24] = 00 1110
3393      instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit, 11=> 64-bit
3394      instr[21,10] = 11 0001 1011 10
3395      instr[9,5]   = Vm
3396      instr[4.0]   = Rd.  */
3397
3398   unsigned vm = INSTR (9, 5);
3399   unsigned rd = INSTR (4, 0);
3400   unsigned i;
3401   uint64_t val = 0;
3402   int      full = INSTR (30, 30);
3403
3404   NYI_assert (29, 24, 0x0E);
3405   NYI_assert (21, 10, 0xC6E);
3406
3407   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3408   switch (INSTR (23, 22))
3409     {
3410     case 0:
3411       for (i = 0; i < (full ? 16 : 8); i++)
3412         val += aarch64_get_vec_u8 (cpu, vm, i);
3413       aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
3414       return;
3415
3416     case 1:
3417       for (i = 0; i < (full ? 8 : 4); i++)
3418         val += aarch64_get_vec_u16 (cpu, vm, i);
3419       aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
3420       return;
3421
3422     case 2:
3423       for (i = 0; i < (full ? 4 : 2); i++)
3424         val += aarch64_get_vec_u32 (cpu, vm, i);
3425       aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
3426       return;
3427
3428     case 3:
3429       if (! full)
3430         HALT_UNALLOC;
3431       val = aarch64_get_vec_u64 (cpu, vm, 0);
3432       val += aarch64_get_vec_u64 (cpu, vm, 1);
3433       aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
3434       return;
3435     }
3436 }
3437
3438 static void
3439 do_vec_ins_2 (sim_cpu *cpu)
3440 {
3441   /* instr[31,21] = 01001110000
3442      instr[20,18] = size & element selector
3443      instr[17,14] = 0000
3444      instr[13]    = direction: to vec(0), from vec (1)
3445      instr[12,10] = 111
3446      instr[9,5]   = Vm
3447      instr[4,0]   = Vd.  */
3448
3449   unsigned elem;
3450   unsigned vm = INSTR (9, 5);
3451   unsigned vd = INSTR (4, 0);
3452
3453   NYI_assert (31, 21, 0x270);
3454   NYI_assert (17, 14, 0);
3455   NYI_assert (12, 10, 7);
3456
3457   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3458   if (INSTR (13, 13) == 1)
3459     {
3460       if (INSTR (18, 18) == 1)
3461         {
3462           /* 32-bit moves.  */
3463           elem = INSTR (20, 19);
3464           aarch64_set_reg_u64 (cpu, vd, NO_SP,
3465                                aarch64_get_vec_u32 (cpu, vm, elem));
3466         }
3467       else
3468         {
3469           /* 64-bit moves.  */
3470           if (INSTR (19, 19) != 1)
3471             HALT_NYI;
3472
3473           elem = INSTR (20, 20);
3474           aarch64_set_reg_u64 (cpu, vd, NO_SP,
3475                                aarch64_get_vec_u64 (cpu, vm, elem));
3476         }
3477     }
3478   else
3479     {
3480       if (INSTR (18, 18) == 1)
3481         {
3482           /* 32-bit moves.  */
3483           elem = INSTR (20, 19);
3484           aarch64_set_vec_u32 (cpu, vd, elem,
3485                                aarch64_get_reg_u32 (cpu, vm, NO_SP));
3486         }
3487       else
3488         {
3489           /* 64-bit moves.  */
3490           if (INSTR (19, 19) != 1)
3491             HALT_NYI;
3492
3493           elem = INSTR (20, 20);
3494           aarch64_set_vec_u64 (cpu, vd, elem,
3495                                aarch64_get_reg_u64 (cpu, vm, NO_SP));
3496         }
3497     }
3498 }
3499
3500 #define DO_VEC_WIDENING_MUL(N, DST_TYPE, READ_TYPE, WRITE_TYPE)   \
3501   do                                                              \
3502     {                                                             \
3503       DST_TYPE a[N], b[N];                                        \
3504                                                                   \
3505       for (i = 0; i < (N); i++)                                   \
3506         {                                                         \
3507           a[i] = aarch64_get_vec_##READ_TYPE (cpu, vn, i + bias); \
3508           b[i] = aarch64_get_vec_##READ_TYPE (cpu, vm, i + bias); \
3509         }                                                         \
3510       for (i = 0; i < (N); i++)                                   \
3511         aarch64_set_vec_##WRITE_TYPE (cpu, vd, i, a[i] * b[i]);   \
3512     }                                                             \
3513   while (0)
3514
3515 static void
3516 do_vec_mull (sim_cpu *cpu)
3517 {
3518   /* instr[31]    = 0
3519      instr[30]    = lower(0)/upper(1) selector
3520      instr[29]    = signed(0)/unsigned(1)
3521      instr[28,24] = 0 1110
3522      instr[23,22] = size: 8-bit (00), 16-bit (01), 32-bit (10)
3523      instr[21]    = 1
3524      instr[20,16] = Vm
3525      instr[15,10] = 11 0000
3526      instr[9,5]   = Vn
3527      instr[4.0]   = Vd.  */
3528
3529   int    unsign = INSTR (29, 29);
3530   int    bias = INSTR (30, 30);
3531   unsigned vm = INSTR (20, 16);
3532   unsigned vn = INSTR ( 9,  5);
3533   unsigned vd = INSTR ( 4,  0);
3534   unsigned i;
3535
3536   NYI_assert (28, 24, 0x0E);
3537   NYI_assert (15, 10, 0x30);
3538
3539   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3540   /* NB: Read source values before writing results, in case
3541      the source and destination vectors are the same.  */
3542   switch (INSTR (23, 22))
3543     {
3544     case 0:
3545       if (bias)
3546         bias = 8;
3547       if (unsign)
3548         DO_VEC_WIDENING_MUL (8, uint16_t, u8, u16);
3549       else
3550         DO_VEC_WIDENING_MUL (8, int16_t, s8, s16);
3551       return;
3552
3553     case 1:
3554       if (bias)
3555         bias = 4;
3556       if (unsign)
3557         DO_VEC_WIDENING_MUL (4, uint32_t, u16, u32);
3558       else
3559         DO_VEC_WIDENING_MUL (4, int32_t, s16, s32);
3560       return;
3561
3562     case 2:
3563       if (bias)
3564         bias = 2;
3565       if (unsign)
3566         DO_VEC_WIDENING_MUL (2, uint64_t, u32, u64);
3567       else
3568         DO_VEC_WIDENING_MUL (2, int64_t, s32, s64);
3569       return;
3570
3571     case 3:
3572       HALT_NYI;
3573     }
3574 }
3575
3576 static void
3577 do_vec_fadd (sim_cpu *cpu)
3578 {
3579   /* instr[31]    = 0
3580      instr[30]    = half(0)/full(1)
3581      instr[29,24] = 001110
3582      instr[23]    = FADD(0)/FSUB(1)
3583      instr[22]    = float (0)/double(1)
3584      instr[21]    = 1
3585      instr[20,16] = Vm
3586      instr[15,10] = 110101
3587      instr[9,5]   = Vn
3588      instr[4.0]   = Vd.  */
3589
3590   unsigned vm = INSTR (20, 16);
3591   unsigned vn = INSTR (9, 5);
3592   unsigned vd = INSTR (4, 0);
3593   unsigned i;
3594   int      full = INSTR (30, 30);
3595
3596   NYI_assert (29, 24, 0x0E);
3597   NYI_assert (21, 21, 1);
3598   NYI_assert (15, 10, 0x35);
3599
3600   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3601   if (INSTR (23, 23))
3602     {
3603       if (INSTR (22, 22))
3604         {
3605           if (! full)
3606             HALT_NYI;
3607
3608           for (i = 0; i < 2; i++)
3609             aarch64_set_vec_double (cpu, vd, i,
3610                                     aarch64_get_vec_double (cpu, vn, i)
3611                                     - aarch64_get_vec_double (cpu, vm, i));
3612         }
3613       else
3614         {
3615           for (i = 0; i < (full ? 4 : 2); i++)
3616             aarch64_set_vec_float (cpu, vd, i,
3617                                    aarch64_get_vec_float (cpu, vn, i)
3618                                    - aarch64_get_vec_float (cpu, vm, i));
3619         }
3620     }
3621   else
3622     {
3623       if (INSTR (22, 22))
3624         {
3625           if (! full)
3626             HALT_NYI;
3627
3628           for (i = 0; i < 2; i++)
3629             aarch64_set_vec_double (cpu, vd, i,
3630                                     aarch64_get_vec_double (cpu, vm, i)
3631                                     + aarch64_get_vec_double (cpu, vn, i));
3632         }
3633       else
3634         {
3635           for (i = 0; i < (full ? 4 : 2); i++)
3636             aarch64_set_vec_float (cpu, vd, i,
3637                                    aarch64_get_vec_float (cpu, vm, i)
3638                                    + aarch64_get_vec_float (cpu, vn, i));
3639         }
3640     }
3641 }
3642
3643 static void
3644 do_vec_add (sim_cpu *cpu)
3645 {
3646   /* instr[31]    = 0
3647      instr[30]    = full/half selector
3648      instr[29,24] = 001110
3649      instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit, 11=> 64-bit
3650      instr[21]    = 1
3651      instr[20,16] = Vn
3652      instr[15,10] = 100001
3653      instr[9,5]   = Vm
3654      instr[4.0]   = Vd.  */
3655
3656   unsigned vm = INSTR (20, 16);
3657   unsigned vn = INSTR (9, 5);
3658   unsigned vd = INSTR (4, 0);
3659   unsigned i;
3660   int      full = INSTR (30, 30);
3661
3662   NYI_assert (29, 24, 0x0E);
3663   NYI_assert (21, 21, 1);
3664   NYI_assert (15, 10, 0x21);
3665
3666   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3667   switch (INSTR (23, 22))
3668     {
3669     case 0:
3670       for (i = 0; i < (full ? 16 : 8); i++)
3671         aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vn, i)
3672                             + aarch64_get_vec_u8 (cpu, vm, i));
3673       return;
3674
3675     case 1:
3676       for (i = 0; i < (full ? 8 : 4); i++)
3677         aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vn, i)
3678                              + aarch64_get_vec_u16 (cpu, vm, i));
3679       return;
3680
3681     case 2:
3682       for (i = 0; i < (full ? 4 : 2); i++)
3683         aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vn, i)
3684                              + aarch64_get_vec_u32 (cpu, vm, i));
3685       return;
3686
3687     case 3:
3688       if (! full)
3689         HALT_UNALLOC;
3690       aarch64_set_vec_u64 (cpu, vd, 0, aarch64_get_vec_u64 (cpu, vn, 0)
3691                            + aarch64_get_vec_u64 (cpu, vm, 0));
3692       aarch64_set_vec_u64 (cpu, vd, 1,
3693                            aarch64_get_vec_u64 (cpu, vn, 1)
3694                            + aarch64_get_vec_u64 (cpu, vm, 1));
3695       return;
3696     }
3697 }
3698
3699 static void
3700 do_vec_mul (sim_cpu *cpu)
3701 {
3702   /* instr[31]    = 0
3703      instr[30]    = full/half selector
3704      instr[29,24] = 00 1110
3705      instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit
3706      instr[21]    = 1
3707      instr[20,16] = Vn
3708      instr[15,10] = 10 0111
3709      instr[9,5]   = Vm
3710      instr[4.0]   = Vd.  */
3711
3712   unsigned vm = INSTR (20, 16);
3713   unsigned vn = INSTR (9, 5);
3714   unsigned vd = INSTR (4, 0);
3715   unsigned i;
3716   int      full = INSTR (30, 30);
3717   int      bias = 0;
3718
3719   NYI_assert (29, 24, 0x0E);
3720   NYI_assert (21, 21, 1);
3721   NYI_assert (15, 10, 0x27);
3722
3723   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3724   switch (INSTR (23, 22))
3725     {
3726     case 0:
3727       DO_VEC_WIDENING_MUL (full ? 16 : 8, uint16_t, u8, u16);
3728       return;
3729
3730     case 1:
3731       DO_VEC_WIDENING_MUL (full ? 8 : 4, uint32_t, u16, u32);
3732       return;
3733
3734     case 2:
3735       DO_VEC_WIDENING_MUL (full ? 4 : 2, uint64_t, u32, u64);
3736       return;
3737
3738     case 3:
3739       HALT_UNALLOC;
3740     }
3741 }
3742
3743 static void
3744 do_vec_MLA (sim_cpu *cpu)
3745 {
3746   /* instr[31]    = 0
3747      instr[30]    = full/half selector
3748      instr[29,24] = 00 1110
3749      instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit
3750      instr[21]    = 1
3751      instr[20,16] = Vn
3752      instr[15,10] = 1001 01
3753      instr[9,5]   = Vm
3754      instr[4.0]   = Vd.  */
3755
3756   unsigned vm = INSTR (20, 16);
3757   unsigned vn = INSTR (9, 5);
3758   unsigned vd = INSTR (4, 0);
3759   unsigned i;
3760   int      full = INSTR (30, 30);
3761
3762   NYI_assert (29, 24, 0x0E);
3763   NYI_assert (21, 21, 1);
3764   NYI_assert (15, 10, 0x25);
3765
3766   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3767   switch (INSTR (23, 22))
3768     {
3769     case 0:
3770       {
3771         uint16_t a[16], b[16];
3772
3773         for (i = 0; i < (full ? 16 : 8); i++)
3774           {
3775             a[i] = aarch64_get_vec_u8 (cpu, vn, i);
3776             b[i] = aarch64_get_vec_u8 (cpu, vm, i);
3777           }
3778         
3779         for (i = 0; i < (full ? 16 : 8); i++)
3780           {
3781             uint16_t v = aarch64_get_vec_u8 (cpu, vd, i);
3782
3783             aarch64_set_vec_u16 (cpu, vd, i, v + (a[i] * b[i]));
3784           }
3785       }
3786       return;
3787
3788     case 1:
3789       {
3790         uint32_t a[8], b[8];
3791
3792         for (i = 0; i < (full ? 8 : 4); i++)
3793           {
3794             a[i] = aarch64_get_vec_u16 (cpu, vn, i);
3795             b[i] = aarch64_get_vec_u16 (cpu, vm, i);
3796           }
3797         
3798         for (i = 0; i < (full ? 8 : 4); i++)
3799           {
3800             uint32_t v = aarch64_get_vec_u16 (cpu, vd, i);
3801
3802             aarch64_set_vec_u32 (cpu, vd, i, v + (a[i] * b[i]));
3803           }
3804       }
3805       return;
3806
3807     case 2:
3808       {
3809         uint64_t a[4], b[4];
3810
3811         for (i = 0; i < (full ? 4 : 2); i++)
3812           {
3813             a[i] = aarch64_get_vec_u32 (cpu, vn, i);
3814             b[i] = aarch64_get_vec_u32 (cpu, vm, i);
3815           }
3816         
3817         for (i = 0; i < (full ? 4 : 2); i++)
3818           {
3819             uint64_t v = aarch64_get_vec_u32 (cpu, vd, i);
3820
3821             aarch64_set_vec_u64 (cpu, vd, i, v + (a[i] * b[i]));
3822           }
3823       }
3824       return;
3825
3826     case 3:
3827       HALT_UNALLOC;
3828     }
3829 }
3830
3831 static float
3832 fmaxnm (float a, float b)
3833 {
3834   if (fpclassify (a) == FP_NORMAL)
3835     {
3836       if (fpclassify (b) == FP_NORMAL)
3837         return a > b ? a : b;
3838       return a;
3839     }
3840   else if (fpclassify (b) == FP_NORMAL)
3841     return b;
3842   return a;
3843 }
3844
3845 static float
3846 fminnm (float a, float b)
3847 {
3848   if (fpclassify (a) == FP_NORMAL)
3849     {
3850       if (fpclassify (b) == FP_NORMAL)
3851         return a < b ? a : b;
3852       return a;
3853     }
3854   else if (fpclassify (b) == FP_NORMAL)
3855     return b;
3856   return a;
3857 }
3858
3859 static double
3860 dmaxnm (double a, double b)
3861 {
3862   if (fpclassify (a) == FP_NORMAL)
3863     {
3864       if (fpclassify (b) == FP_NORMAL)
3865         return a > b ? a : b;
3866       return a;
3867     }
3868   else if (fpclassify (b) == FP_NORMAL)
3869     return b;
3870   return a;
3871 }
3872
3873 static double
3874 dminnm (double a, double b)
3875 {
3876   if (fpclassify (a) == FP_NORMAL)
3877     {
3878       if (fpclassify (b) == FP_NORMAL)
3879         return a < b ? a : b;
3880       return a;
3881     }
3882   else if (fpclassify (b) == FP_NORMAL)
3883     return b;
3884   return a;
3885 }
3886
3887 static void
3888 do_vec_FminmaxNMP (sim_cpu *cpu)
3889 {
3890   /* instr [31]    = 0
3891      instr [30]    = half (0)/full (1)
3892      instr [29,24] = 10 1110
3893      instr [23]    = max(0)/min(1)
3894      instr [22]    = float (0)/double (1)
3895      instr [21]    = 1
3896      instr [20,16] = Vn
3897      instr [15,10] = 1100 01
3898      instr [9,5]   = Vm
3899      instr [4.0]   = Vd.  */
3900
3901   unsigned vm = INSTR (20, 16);
3902   unsigned vn = INSTR (9, 5);
3903   unsigned vd = INSTR (4, 0);
3904   int      full = INSTR (30, 30);
3905
3906   NYI_assert (29, 24, 0x2E);
3907   NYI_assert (21, 21, 1);
3908   NYI_assert (15, 10, 0x31);
3909
3910   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3911   if (INSTR (22, 22))
3912     {
3913       double (* fn)(double, double) = INSTR (23, 23)
3914         ? dminnm : dmaxnm;
3915
3916       if (! full)
3917         HALT_NYI;
3918       aarch64_set_vec_double (cpu, vd, 0,
3919                               fn (aarch64_get_vec_double (cpu, vn, 0),
3920                                   aarch64_get_vec_double (cpu, vn, 1)));
3921       aarch64_set_vec_double (cpu, vd, 0,
3922                               fn (aarch64_get_vec_double (cpu, vm, 0),
3923                                   aarch64_get_vec_double (cpu, vm, 1)));
3924     }
3925   else
3926     {
3927       float (* fn)(float, float) = INSTR (23, 23)
3928         ? fminnm : fmaxnm;
3929
3930       aarch64_set_vec_float (cpu, vd, 0,
3931                              fn (aarch64_get_vec_float (cpu, vn, 0),
3932                                  aarch64_get_vec_float (cpu, vn, 1)));
3933       if (full)
3934         aarch64_set_vec_float (cpu, vd, 1,
3935                                fn (aarch64_get_vec_float (cpu, vn, 2),
3936                                    aarch64_get_vec_float (cpu, vn, 3)));
3937
3938       aarch64_set_vec_float (cpu, vd, (full ? 2 : 1),
3939                              fn (aarch64_get_vec_float (cpu, vm, 0),
3940                                  aarch64_get_vec_float (cpu, vm, 1)));
3941       if (full)
3942         aarch64_set_vec_float (cpu, vd, 3,
3943                                fn (aarch64_get_vec_float (cpu, vm, 2),
3944                                    aarch64_get_vec_float (cpu, vm, 3)));
3945     }
3946 }
3947
3948 static void
3949 do_vec_AND (sim_cpu *cpu)
3950 {
3951   /* instr[31]    = 0
3952      instr[30]    = half (0)/full (1)
3953      instr[29,21] = 001110001
3954      instr[20,16] = Vm
3955      instr[15,10] = 000111
3956      instr[9,5]   = Vn
3957      instr[4.0]   = Vd.  */
3958
3959   unsigned vm = INSTR (20, 16);
3960   unsigned vn = INSTR (9, 5);
3961   unsigned vd = INSTR (4, 0);
3962   unsigned i;
3963   int      full = INSTR (30, 30);
3964
3965   NYI_assert (29, 21, 0x071);
3966   NYI_assert (15, 10, 0x07);
3967
3968   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3969   for (i = 0; i < (full ? 4 : 2); i++)
3970     aarch64_set_vec_u32 (cpu, vd, i,
3971                          aarch64_get_vec_u32 (cpu, vn, i)
3972                          & aarch64_get_vec_u32 (cpu, vm, i));
3973 }
3974
3975 static void
3976 do_vec_BSL (sim_cpu *cpu)
3977 {
3978   /* instr[31]    = 0
3979      instr[30]    = half (0)/full (1)
3980      instr[29,21] = 101110011
3981      instr[20,16] = Vm
3982      instr[15,10] = 000111
3983      instr[9,5]   = Vn
3984      instr[4.0]   = Vd.  */
3985
3986   unsigned vm = INSTR (20, 16);
3987   unsigned vn = INSTR (9, 5);
3988   unsigned vd = INSTR (4, 0);
3989   unsigned i;
3990   int      full = INSTR (30, 30);
3991
3992   NYI_assert (29, 21, 0x173);
3993   NYI_assert (15, 10, 0x07);
3994
3995   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
3996   for (i = 0; i < (full ? 16 : 8); i++)
3997     aarch64_set_vec_u8 (cpu, vd, i,
3998                         (    aarch64_get_vec_u8 (cpu, vd, i)
3999                            & aarch64_get_vec_u8 (cpu, vn, i))
4000                         | ((~ aarch64_get_vec_u8 (cpu, vd, i))
4001                            & aarch64_get_vec_u8 (cpu, vm, i)));
4002 }
4003
4004 static void
4005 do_vec_EOR (sim_cpu *cpu)
4006 {
4007   /* instr[31]    = 0
4008      instr[30]    = half (0)/full (1)
4009      instr[29,21] = 10 1110 001
4010      instr[20,16] = Vm
4011      instr[15,10] = 000111
4012      instr[9,5]   = Vn
4013      instr[4.0]   = Vd.  */
4014
4015   unsigned vm = INSTR (20, 16);
4016   unsigned vn = INSTR (9, 5);
4017   unsigned vd = INSTR (4, 0);
4018   unsigned i;
4019   int      full = INSTR (30, 30);
4020
4021   NYI_assert (29, 21, 0x171);
4022   NYI_assert (15, 10, 0x07);
4023
4024   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4025   for (i = 0; i < (full ? 4 : 2); i++)
4026     aarch64_set_vec_u32 (cpu, vd, i,
4027                          aarch64_get_vec_u32 (cpu, vn, i)
4028                          ^ aarch64_get_vec_u32 (cpu, vm, i));
4029 }
4030
4031 static void
4032 do_vec_bit (sim_cpu *cpu)
4033 {
4034   /* instr[31]    = 0
4035      instr[30]    = half (0)/full (1)
4036      instr[29,23] = 10 1110 1
4037      instr[22]    = BIT (0) / BIF (1)
4038      instr[21]    = 1
4039      instr[20,16] = Vm
4040      instr[15,10] = 0001 11
4041      instr[9,5]   = Vn
4042      instr[4.0]   = Vd.  */
4043
4044   unsigned vm = INSTR (20, 16);
4045   unsigned vn = INSTR (9, 5);
4046   unsigned vd = INSTR (4, 0);
4047   unsigned full = INSTR (30, 30);
4048   unsigned test_false = INSTR (22, 22);
4049   unsigned i;
4050
4051   NYI_assert (29, 23, 0x5D);
4052   NYI_assert (21, 21, 1);
4053   NYI_assert (15, 10, 0x07);
4054
4055   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4056   if (test_false)
4057     {
4058       for (i = 0; i < (full ? 16 : 8); i++)
4059         if (aarch64_get_vec_u32 (cpu, vn, i) == 0)
4060           aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vm, i));
4061     }
4062   else
4063     {
4064       for (i = 0; i < (full ? 16 : 8); i++)
4065         if (aarch64_get_vec_u32 (cpu, vn, i) != 0)
4066           aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vm, i));
4067     }
4068 }
4069
4070 static void
4071 do_vec_ORN (sim_cpu *cpu)
4072 {
4073   /* instr[31]    = 0
4074      instr[30]    = half (0)/full (1)
4075      instr[29,21] = 00 1110 111
4076      instr[20,16] = Vm
4077      instr[15,10] = 00 0111
4078      instr[9,5]   = Vn
4079      instr[4.0]   = Vd.  */
4080
4081   unsigned vm = INSTR (20, 16);
4082   unsigned vn = INSTR (9, 5);
4083   unsigned vd = INSTR (4, 0);
4084   unsigned i;
4085   int      full = INSTR (30, 30);
4086
4087   NYI_assert (29, 21, 0x077);
4088   NYI_assert (15, 10, 0x07);
4089
4090   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4091   for (i = 0; i < (full ? 16 : 8); i++)
4092     aarch64_set_vec_u8 (cpu, vd, i,
4093                         aarch64_get_vec_u8 (cpu, vn, i)
4094                         | ~ aarch64_get_vec_u8 (cpu, vm, i));
4095 }
4096
4097 static void
4098 do_vec_ORR (sim_cpu *cpu)
4099 {
4100   /* instr[31]    = 0
4101      instr[30]    = half (0)/full (1)
4102      instr[29,21] = 00 1110 101
4103      instr[20,16] = Vm
4104      instr[15,10] = 0001 11
4105      instr[9,5]   = Vn
4106      instr[4.0]   = Vd.  */
4107
4108   unsigned vm = INSTR (20, 16);
4109   unsigned vn = INSTR (9, 5);
4110   unsigned vd = INSTR (4, 0);
4111   unsigned i;
4112   int      full = INSTR (30, 30);
4113
4114   NYI_assert (29, 21, 0x075);
4115   NYI_assert (15, 10, 0x07);
4116
4117   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4118   for (i = 0; i < (full ? 16 : 8); i++)
4119     aarch64_set_vec_u8 (cpu, vd, i,
4120                         aarch64_get_vec_u8 (cpu, vn, i)
4121                         | aarch64_get_vec_u8 (cpu, vm, i));
4122 }
4123
4124 static void
4125 do_vec_BIC (sim_cpu *cpu)
4126 {
4127   /* instr[31]    = 0
4128      instr[30]    = half (0)/full (1)
4129      instr[29,21] = 00 1110 011
4130      instr[20,16] = Vm
4131      instr[15,10] = 00 0111
4132      instr[9,5]   = Vn
4133      instr[4.0]   = Vd.  */
4134
4135   unsigned vm = INSTR (20, 16);
4136   unsigned vn = INSTR (9, 5);
4137   unsigned vd = INSTR (4, 0);
4138   unsigned i;
4139   int      full = INSTR (30, 30);
4140
4141   NYI_assert (29, 21, 0x073);
4142   NYI_assert (15, 10, 0x07);
4143
4144   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4145   for (i = 0; i < (full ? 16 : 8); i++)
4146     aarch64_set_vec_u8 (cpu, vd, i,
4147                         aarch64_get_vec_u8 (cpu, vn, i)
4148                         & ~ aarch64_get_vec_u8 (cpu, vm, i));
4149 }
4150
4151 static void
4152 do_vec_XTN (sim_cpu *cpu)
4153 {
4154   /* instr[31]    = 0
4155      instr[30]    = first part (0)/ second part (1)
4156      instr[29,24] = 00 1110
4157      instr[23,22] = size: byte(00), half(01), word (10)
4158      instr[21,10] = 1000 0100 1010
4159      instr[9,5]   = Vs
4160      instr[4,0]   = Vd.  */
4161
4162   unsigned vs = INSTR (9, 5);
4163   unsigned vd = INSTR (4, 0);
4164   unsigned bias = INSTR (30, 30);
4165   unsigned i;
4166
4167   NYI_assert (29, 24, 0x0E);
4168   NYI_assert (21, 10, 0x84A);
4169
4170   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4171   switch (INSTR (23, 22))
4172     {
4173     case 0:
4174       if (bias)
4175         for (i = 0; i < 8; i++)
4176           aarch64_set_vec_u8 (cpu, vd, i + 8,
4177                               aarch64_get_vec_u16 (cpu, vs, i) >> 8);
4178       else
4179         for (i = 0; i < 8; i++)
4180           aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vs, i));
4181       return;
4182
4183     case 1:
4184       if (bias)
4185         for (i = 0; i < 4; i++)
4186           aarch64_set_vec_u16 (cpu, vd, i + 4,
4187                                aarch64_get_vec_u32 (cpu, vs, i) >> 16);
4188       else
4189         for (i = 0; i < 4; i++)
4190           aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vs, i));
4191       return;
4192
4193     case 2:
4194       if (bias)
4195         for (i = 0; i < 2; i++)
4196           aarch64_set_vec_u32 (cpu, vd, i + 4,
4197                                aarch64_get_vec_u64 (cpu, vs, i) >> 32);
4198       else
4199         for (i = 0; i < 2; i++)
4200           aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vs, i));
4201       return;
4202     }
4203 }
4204
4205 static void
4206 do_vec_maxv (sim_cpu *cpu)
4207 {
4208   /* instr[31]    = 0
4209      instr[30]    = half(0)/full(1)
4210      instr[29]    = signed (0)/unsigned(1)
4211      instr[28,24] = 0 1110
4212      instr[23,22] = size: byte(00), half(01), word (10)
4213      instr[21]    = 1
4214      instr[20,17] = 1 000
4215      instr[16]    = max(0)/min(1)
4216      instr[15,10] = 1010 10
4217      instr[9,5]   = V source
4218      instr[4.0]   = R dest.  */
4219
4220   unsigned vs = INSTR (9, 5);
4221   unsigned rd = INSTR (4, 0);
4222   unsigned full = INSTR (30, 30);
4223   unsigned i;
4224
4225   NYI_assert (28, 24, 0x0E);
4226   NYI_assert (21, 21, 1);
4227   NYI_assert (20, 17, 8);
4228   NYI_assert (15, 10, 0x2A);
4229
4230   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4231   switch ((INSTR (29, 29) << 1) | INSTR (16, 16))
4232     {
4233     case 0: /* SMAXV.  */
4234        {
4235         int64_t smax;
4236         switch (INSTR (23, 22))
4237           {
4238           case 0:
4239             smax = aarch64_get_vec_s8 (cpu, vs, 0);
4240             for (i = 1; i < (full ? 16 : 8); i++)
4241               smax = max (smax, aarch64_get_vec_s8 (cpu, vs, i));
4242             break;
4243           case 1:
4244             smax = aarch64_get_vec_s16 (cpu, vs, 0);
4245             for (i = 1; i < (full ? 8 : 4); i++)
4246               smax = max (smax, aarch64_get_vec_s16 (cpu, vs, i));
4247             break;
4248           case 2:
4249             smax = aarch64_get_vec_s32 (cpu, vs, 0);
4250             for (i = 1; i < (full ? 4 : 2); i++)
4251               smax = max (smax, aarch64_get_vec_s32 (cpu, vs, i));
4252             break;
4253           case 3:
4254             HALT_UNALLOC;
4255           }
4256         aarch64_set_reg_s64 (cpu, rd, NO_SP, smax);
4257         return;
4258       }
4259
4260     case 1: /* SMINV.  */
4261       {
4262         int64_t smin;
4263         switch (INSTR (23, 22))
4264           {
4265           case 0:
4266             smin = aarch64_get_vec_s8 (cpu, vs, 0);
4267             for (i = 1; i < (full ? 16 : 8); i++)
4268               smin = min (smin, aarch64_get_vec_s8 (cpu, vs, i));
4269             break;
4270           case 1:
4271             smin = aarch64_get_vec_s16 (cpu, vs, 0);
4272             for (i = 1; i < (full ? 8 : 4); i++)
4273               smin = min (smin, aarch64_get_vec_s16 (cpu, vs, i));
4274             break;
4275           case 2:
4276             smin = aarch64_get_vec_s32 (cpu, vs, 0);
4277             for (i = 1; i < (full ? 4 : 2); i++)
4278               smin = min (smin, aarch64_get_vec_s32 (cpu, vs, i));
4279             break;
4280
4281           case 3:
4282             HALT_UNALLOC;
4283           }
4284         aarch64_set_reg_s64 (cpu, rd, NO_SP, smin);
4285         return;
4286       }
4287
4288     case 2: /* UMAXV.  */
4289       {
4290         uint64_t umax;
4291         switch (INSTR (23, 22))
4292           {
4293           case 0:
4294             umax = aarch64_get_vec_u8 (cpu, vs, 0);
4295             for (i = 1; i < (full ? 16 : 8); i++)
4296               umax = max (umax, aarch64_get_vec_u8 (cpu, vs, i));
4297             break;
4298           case 1:
4299             umax = aarch64_get_vec_u16 (cpu, vs, 0);
4300             for (i = 1; i < (full ? 8 : 4); i++)
4301               umax = max (umax, aarch64_get_vec_u16 (cpu, vs, i));
4302             break;
4303           case 2:
4304             umax = aarch64_get_vec_u32 (cpu, vs, 0);
4305             for (i = 1; i < (full ? 4 : 2); i++)
4306               umax = max (umax, aarch64_get_vec_u32 (cpu, vs, i));
4307             break;
4308
4309           case 3:
4310             HALT_UNALLOC;
4311           }
4312         aarch64_set_reg_u64 (cpu, rd, NO_SP, umax);
4313         return;
4314       }
4315
4316     case 3: /* UMINV.  */
4317       {
4318         uint64_t umin;
4319         switch (INSTR (23, 22))
4320           {
4321           case 0:
4322             umin = aarch64_get_vec_u8 (cpu, vs, 0);
4323             for (i = 1; i < (full ? 16 : 8); i++)
4324               umin = min (umin, aarch64_get_vec_u8 (cpu, vs, i));
4325             break;
4326           case 1:
4327             umin = aarch64_get_vec_u16 (cpu, vs, 0);
4328             for (i = 1; i < (full ? 8 : 4); i++)
4329               umin = min (umin, aarch64_get_vec_u16 (cpu, vs, i));
4330             break;
4331           case 2:
4332             umin = aarch64_get_vec_u32 (cpu, vs, 0);
4333             for (i = 1; i < (full ? 4 : 2); i++)
4334               umin = min (umin, aarch64_get_vec_u32 (cpu, vs, i));
4335             break;
4336
4337           case 3:
4338             HALT_UNALLOC;
4339           }
4340         aarch64_set_reg_u64 (cpu, rd, NO_SP, umin);
4341         return;
4342       }
4343     }
4344 }
4345
4346 static void
4347 do_vec_fminmaxV (sim_cpu *cpu)
4348 {
4349   /* instr[31,24] = 0110 1110
4350      instr[23]    = max(0)/min(1)
4351      instr[22,14] = 011 0000 11
4352      instr[13,12] = nm(00)/normal(11)
4353      instr[11,10] = 10
4354      instr[9,5]   = V source
4355      instr[4.0]   = R dest.  */
4356
4357   unsigned vs = INSTR (9, 5);
4358   unsigned rd = INSTR (4, 0);
4359   unsigned i;
4360   float res   = aarch64_get_vec_float (cpu, vs, 0);
4361
4362   NYI_assert (31, 24, 0x6E);
4363   NYI_assert (22, 14, 0x0C3);
4364   NYI_assert (11, 10, 2);
4365
4366   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4367   if (INSTR (23, 23))
4368     {
4369       switch (INSTR (13, 12))
4370         {
4371         case 0: /* FMNINNMV.  */
4372           for (i = 1; i < 4; i++)
4373             res = fminnm (res, aarch64_get_vec_float (cpu, vs, i));
4374           break;
4375
4376         case 3: /* FMINV.  */
4377           for (i = 1; i < 4; i++)
4378             res = min (res, aarch64_get_vec_float (cpu, vs, i));
4379           break;
4380
4381         default:
4382           HALT_NYI;
4383         }
4384     }
4385   else
4386     {
4387       switch (INSTR (13, 12))
4388         {
4389         case 0: /* FMNAXNMV.  */
4390           for (i = 1; i < 4; i++)
4391             res = fmaxnm (res, aarch64_get_vec_float (cpu, vs, i));
4392           break;
4393
4394         case 3: /* FMAXV.  */
4395           for (i = 1; i < 4; i++)
4396             res = max (res, aarch64_get_vec_float (cpu, vs, i));
4397           break;
4398
4399         default:
4400           HALT_NYI;
4401         }
4402     }
4403
4404   aarch64_set_FP_float (cpu, rd, res);
4405 }
4406
4407 static void
4408 do_vec_Fminmax (sim_cpu *cpu)
4409 {
4410   /* instr[31]    = 0
4411      instr[30]    = half(0)/full(1)
4412      instr[29,24] = 00 1110
4413      instr[23]    = max(0)/min(1)
4414      instr[22]    = float(0)/double(1)
4415      instr[21]    = 1
4416      instr[20,16] = Vm
4417      instr[15,14] = 11
4418      instr[13,12] = nm(00)/normal(11)
4419      instr[11,10] = 01
4420      instr[9,5]   = Vn
4421      instr[4,0]   = Vd.  */
4422
4423   unsigned vm = INSTR (20, 16);
4424   unsigned vn = INSTR (9, 5);
4425   unsigned vd = INSTR (4, 0);
4426   unsigned full = INSTR (30, 30);
4427   unsigned min = INSTR (23, 23);
4428   unsigned i;
4429
4430   NYI_assert (29, 24, 0x0E);
4431   NYI_assert (21, 21, 1);
4432   NYI_assert (15, 14, 3);
4433   NYI_assert (11, 10, 1);
4434
4435   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4436   if (INSTR (22, 22))
4437     {
4438       double (* func)(double, double);
4439
4440       if (! full)
4441         HALT_NYI;
4442
4443       if (INSTR (13, 12) == 0)
4444         func = min ? dminnm : dmaxnm;
4445       else if (INSTR (13, 12) == 3)
4446         func = min ? fmin : fmax;
4447       else
4448         HALT_NYI;
4449
4450       for (i = 0; i < 2; i++)
4451         aarch64_set_vec_double (cpu, vd, i,
4452                                 func (aarch64_get_vec_double (cpu, vn, i),
4453                                       aarch64_get_vec_double (cpu, vm, i)));
4454     }
4455   else
4456     {
4457       float (* func)(float, float);
4458
4459       if (INSTR (13, 12) == 0)
4460         func = min ? fminnm : fmaxnm;
4461       else if (INSTR (13, 12) == 3)
4462         func = min ? fminf : fmaxf;
4463       else
4464         HALT_NYI;
4465
4466       for (i = 0; i < (full ? 4 : 2); i++)
4467         aarch64_set_vec_float (cpu, vd, i,
4468                                func (aarch64_get_vec_float (cpu, vn, i),
4469                                      aarch64_get_vec_float (cpu, vm, i)));
4470     }
4471 }
4472
4473 static void
4474 do_vec_SCVTF (sim_cpu *cpu)
4475 {
4476   /* instr[31]    = 0
4477      instr[30]    = Q
4478      instr[29,23] = 00 1110 0
4479      instr[22]    = float(0)/double(1)
4480      instr[21,10] = 10 0001 1101 10
4481      instr[9,5]   = Vn
4482      instr[4,0]   = Vd.  */
4483
4484   unsigned vn = INSTR (9, 5);
4485   unsigned vd = INSTR (4, 0);
4486   unsigned full = INSTR (30, 30);
4487   unsigned size = INSTR (22, 22);
4488   unsigned i;
4489
4490   NYI_assert (29, 23, 0x1C);
4491   NYI_assert (21, 10, 0x876);
4492
4493   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4494   if (size)
4495     {
4496       if (! full)
4497         HALT_UNALLOC;
4498
4499       for (i = 0; i < 2; i++)
4500         {
4501           double val = (double) aarch64_get_vec_u64 (cpu, vn, i);
4502           aarch64_set_vec_double (cpu, vd, i, val);
4503         }
4504     }
4505   else
4506     {
4507       for (i = 0; i < (full ? 4 : 2); i++)
4508         {
4509           float val = (float) aarch64_get_vec_u32 (cpu, vn, i);
4510           aarch64_set_vec_float (cpu, vd, i, val);
4511         }
4512     }
4513 }
4514
4515 #define VEC_CMP(SOURCE, CMP)                                            \
4516   do                                                                    \
4517     {                                                                   \
4518       switch (size)                                                     \
4519         {                                                               \
4520         case 0:                                                         \
4521           for (i = 0; i < (full ? 16 : 8); i++)                         \
4522             aarch64_set_vec_u8 (cpu, vd, i,                             \
4523                                 aarch64_get_vec_##SOURCE##8 (cpu, vn, i) \
4524                                 CMP                                     \
4525                                 aarch64_get_vec_##SOURCE##8 (cpu, vm, i) \
4526                                 ? -1 : 0);                              \
4527           return;                                                       \
4528         case 1:                                                         \
4529           for (i = 0; i < (full ? 8 : 4); i++)                          \
4530             aarch64_set_vec_u16 (cpu, vd, i,                            \
4531                                  aarch64_get_vec_##SOURCE##16 (cpu, vn, i) \
4532                                  CMP                                    \
4533                                  aarch64_get_vec_##SOURCE##16 (cpu, vm, i) \
4534                                  ? -1 : 0);                             \
4535           return;                                                       \
4536         case 2:                                                         \
4537           for (i = 0; i < (full ? 4 : 2); i++)                          \
4538             aarch64_set_vec_u32 (cpu, vd, i, \
4539                                  aarch64_get_vec_##SOURCE##32 (cpu, vn, i) \
4540                                  CMP                                    \
4541                                  aarch64_get_vec_##SOURCE##32 (cpu, vm, i) \
4542                                  ? -1 : 0);                             \
4543           return;                                                       \
4544         case 3:                                                         \
4545           if (! full)                                                   \
4546             HALT_UNALLOC;                                               \
4547           for (i = 0; i < 2; i++)                                       \
4548             aarch64_set_vec_u64 (cpu, vd, i, \
4549                                  aarch64_get_vec_##SOURCE##64 (cpu, vn, i) \
4550                                  CMP                                    \
4551                                  aarch64_get_vec_##SOURCE##64 (cpu, vm, i) \
4552                                  ? -1ULL : 0);                          \
4553           return;                                                       \
4554         }                                                               \
4555     }                                                                   \
4556   while (0)
4557
4558 #define VEC_CMP0(SOURCE, CMP)                                           \
4559   do                                                                    \
4560     {                                                                   \
4561       switch (size)                                                     \
4562         {                                                               \
4563         case 0:                                                         \
4564           for (i = 0; i < (full ? 16 : 8); i++)                         \
4565             aarch64_set_vec_u8 (cpu, vd, i,                             \
4566                                 aarch64_get_vec_##SOURCE##8 (cpu, vn, i) \
4567                                 CMP 0 ? -1 : 0);                        \
4568           return;                                                       \
4569         case 1:                                                         \
4570           for (i = 0; i < (full ? 8 : 4); i++)                          \
4571             aarch64_set_vec_u16 (cpu, vd, i,                            \
4572                                  aarch64_get_vec_##SOURCE##16 (cpu, vn, i) \
4573                                  CMP 0 ? -1 : 0);                       \
4574           return;                                                       \
4575         case 2:                                                         \
4576           for (i = 0; i < (full ? 4 : 2); i++)                          \
4577             aarch64_set_vec_u32 (cpu, vd, i,                            \
4578                                  aarch64_get_vec_##SOURCE##32 (cpu, vn, i) \
4579                                  CMP 0 ? -1 : 0);                       \
4580           return;                                                       \
4581         case 3:                                                         \
4582           if (! full)                                                   \
4583             HALT_UNALLOC;                                               \
4584           for (i = 0; i < 2; i++)                                       \
4585             aarch64_set_vec_u64 (cpu, vd, i,                            \
4586                                  aarch64_get_vec_##SOURCE##64 (cpu, vn, i) \
4587                                  CMP 0 ? -1ULL : 0);                    \
4588           return;                                                       \
4589         }                                                               \
4590     }                                                                   \
4591   while (0)
4592
4593 #define VEC_FCMP0(CMP)                                                  \
4594   do                                                                    \
4595     {                                                                   \
4596       if (vm != 0)                                                      \
4597         HALT_NYI;                                                       \
4598       if (INSTR (22, 22))                                               \
4599         {                                                               \
4600           if (! full)                                                   \
4601             HALT_NYI;                                                   \
4602           for (i = 0; i < 2; i++)                                       \
4603             aarch64_set_vec_u64 (cpu, vd, i,                            \
4604                                  aarch64_get_vec_double (cpu, vn, i)    \
4605                                  CMP 0.0 ? -1 : 0);                     \
4606         }                                                               \
4607       else                                                              \
4608         {                                                               \
4609           for (i = 0; i < (full ? 4 : 2); i++)                          \
4610             aarch64_set_vec_u32 (cpu, vd, i,                            \
4611                                  aarch64_get_vec_float (cpu, vn, i)     \
4612                                  CMP 0.0 ? -1 : 0);                     \
4613         }                                                               \
4614       return;                                                           \
4615     }                                                                   \
4616   while (0)
4617
4618 #define VEC_FCMP(CMP)                                                   \
4619   do                                                                    \
4620     {                                                                   \
4621       if (INSTR (22, 22))                                               \
4622         {                                                               \
4623           if (! full)                                                   \
4624             HALT_NYI;                                                   \
4625           for (i = 0; i < 2; i++)                                       \
4626             aarch64_set_vec_u64 (cpu, vd, i,                            \
4627                                  aarch64_get_vec_double (cpu, vn, i)    \
4628                                  CMP                                    \
4629                                  aarch64_get_vec_double (cpu, vm, i)    \
4630                                  ? -1 : 0);                             \
4631         }                                                               \
4632       else                                                              \
4633         {                                                               \
4634           for (i = 0; i < (full ? 4 : 2); i++)                          \
4635             aarch64_set_vec_u32 (cpu, vd, i,                            \
4636                                  aarch64_get_vec_float (cpu, vn, i)     \
4637                                  CMP                                    \
4638                                  aarch64_get_vec_float (cpu, vm, i)     \
4639                                  ? -1 : 0);                             \
4640         }                                                               \
4641       return;                                                           \
4642     }                                                                   \
4643   while (0)
4644
4645 static void
4646 do_vec_compare (sim_cpu *cpu)
4647 {
4648   /* instr[31]    = 0
4649      instr[30]    = half(0)/full(1)
4650      instr[29]    = part-of-comparison-type
4651      instr[28,24] = 0 1110
4652      instr[23,22] = size of integer compares: byte(00), half(01), word (10), long (11)
4653                     type of float compares: single (-0) / double (-1)
4654      instr[21]    = 1
4655      instr[20,16] = Vm or 00000 (compare vs 0)
4656      instr[15,10] = part-of-comparison-type
4657      instr[9,5]   = Vn
4658      instr[4.0]   = Vd.  */
4659
4660   int full = INSTR (30, 30);
4661   int size = INSTR (23, 22);
4662   unsigned vm = INSTR (20, 16);
4663   unsigned vn = INSTR (9, 5);
4664   unsigned vd = INSTR (4, 0);
4665   unsigned i;
4666
4667   NYI_assert (28, 24, 0x0E);
4668   NYI_assert (21, 21, 1);
4669
4670   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4671   if ((INSTR (11, 11)
4672        && INSTR (14, 14))
4673       || ((INSTR (11, 11) == 0
4674            && INSTR (10, 10) == 0)))
4675     {
4676       /* A compare vs 0.  */
4677       if (vm != 0)
4678         {
4679           if (INSTR (15, 10) == 0x2A)
4680             do_vec_maxv (cpu);
4681           else if (INSTR (15, 10) == 0x32
4682                    || INSTR (15, 10) == 0x3E)
4683             do_vec_fminmaxV (cpu);
4684           else if (INSTR (29, 23) == 0x1C
4685                    && INSTR (21, 10) == 0x876)
4686             do_vec_SCVTF (cpu);
4687           else
4688             HALT_NYI;
4689           return;
4690         }
4691     }
4692
4693   if (INSTR (14, 14))
4694     {
4695       /* A floating point compare.  */
4696       unsigned decode = (INSTR (29, 29) << 5) | (INSTR (23, 23) << 4)
4697         | INSTR (13, 10);
4698
4699       NYI_assert (15, 15, 1);
4700
4701       switch (decode)
4702         {
4703         case /* 0b010010: GT#0 */ 0x12: VEC_FCMP0 (>);
4704         case /* 0b110010: GE#0 */ 0x32: VEC_FCMP0 (>=);
4705         case /* 0b010110: EQ#0 */ 0x16: VEC_FCMP0 (==);
4706         case /* 0b110110: LE#0 */ 0x36: VEC_FCMP0 (<=);
4707         case /* 0b011010: LT#0 */ 0x1A: VEC_FCMP0 (<);
4708         case /* 0b111001: GT */   0x39: VEC_FCMP  (>);
4709         case /* 0b101001: GE */   0x29: VEC_FCMP  (>=);
4710         case /* 0b001001: EQ */   0x09: VEC_FCMP  (==);
4711
4712         default:
4713           HALT_NYI;
4714         }
4715     }
4716   else
4717     {
4718       unsigned decode = (INSTR (29, 29) << 6) | INSTR (15, 10);
4719
4720       switch (decode)
4721         {
4722         case 0x0D: /* 0001101 GT */     VEC_CMP  (s, > );
4723         case 0x0F: /* 0001111 GE */     VEC_CMP  (s, >= );
4724         case 0x22: /* 0100010 GT #0 */  VEC_CMP0 (s, > );
4725         case 0x26: /* 0100110 EQ #0 */  VEC_CMP0 (s, == );
4726         case 0x2A: /* 0101010 LT #0 */  VEC_CMP0 (s, < );
4727         case 0x4D: /* 1001101 HI */     VEC_CMP  (u, > );
4728         case 0x4F: /* 1001111 HS */     VEC_CMP  (u, >= );
4729         case 0x62: /* 1100010 GE #0 */  VEC_CMP0 (s, >= );
4730         case 0x63: /* 1100011 EQ */     VEC_CMP  (u, == );
4731         case 0x66: /* 1100110 LE #0 */  VEC_CMP0 (s, <= );
4732         default:
4733           if (vm == 0)
4734             HALT_NYI;
4735           do_vec_maxv (cpu);
4736         }
4737     }
4738 }
4739
4740 static void
4741 do_vec_SSHL (sim_cpu *cpu)
4742 {
4743   /* instr[31]    = 0
4744      instr[30]    = first part (0)/ second part (1)
4745      instr[29,24] = 00 1110
4746      instr[23,22] = size: byte(00), half(01), word (10), long (11)
4747      instr[21]    = 1
4748      instr[20,16] = Vm
4749      instr[15,10] = 0100 01
4750      instr[9,5]   = Vn
4751      instr[4,0]   = Vd.  */
4752
4753   unsigned full = INSTR (30, 30);
4754   unsigned vm = INSTR (20, 16);
4755   unsigned vn = INSTR (9, 5);
4756   unsigned vd = INSTR (4, 0);
4757   unsigned i;
4758   signed int shift;
4759
4760   NYI_assert (29, 24, 0x0E);
4761   NYI_assert (21, 21, 1);
4762   NYI_assert (15, 10, 0x11);
4763
4764   /* FIXME: What is a signed shift left in this context ?.  */
4765
4766   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4767   switch (INSTR (23, 22))
4768     {
4769     case 0:
4770       for (i = 0; i < (full ? 16 : 8); i++)
4771         {
4772           shift = aarch64_get_vec_s8 (cpu, vm, i);
4773           if (shift >= 0)
4774             aarch64_set_vec_s8 (cpu, vd, i, aarch64_get_vec_s8 (cpu, vn, i)
4775                                 << shift);
4776           else
4777             aarch64_set_vec_s8 (cpu, vd, i, aarch64_get_vec_s8 (cpu, vn, i)
4778                                 >> - shift);
4779         }
4780       return;
4781
4782     case 1:
4783       for (i = 0; i < (full ? 8 : 4); i++)
4784         {
4785           shift = aarch64_get_vec_s8 (cpu, vm, i * 2);
4786           if (shift >= 0)
4787             aarch64_set_vec_s16 (cpu, vd, i, aarch64_get_vec_s16 (cpu, vn, i)
4788                                  << shift);
4789           else
4790             aarch64_set_vec_s16 (cpu, vd, i, aarch64_get_vec_s16 (cpu, vn, i)
4791                                  >> - shift);
4792         }
4793       return;
4794
4795     case 2:
4796       for (i = 0; i < (full ? 4 : 2); i++)
4797         {
4798           shift = aarch64_get_vec_s8 (cpu, vm, i * 4);
4799           if (shift >= 0)
4800             aarch64_set_vec_s32 (cpu, vd, i, aarch64_get_vec_s32 (cpu, vn, i)
4801                                  << shift);
4802           else
4803             aarch64_set_vec_s32 (cpu, vd, i, aarch64_get_vec_s32 (cpu, vn, i)
4804                                  >> - shift);
4805         }
4806       return;
4807
4808     case 3:
4809       if (! full)
4810         HALT_UNALLOC;
4811       for (i = 0; i < 2; i++)
4812         {
4813           shift = aarch64_get_vec_s8 (cpu, vm, i * 8);
4814           if (shift >= 0)
4815             aarch64_set_vec_s64 (cpu, vd, i, aarch64_get_vec_s64 (cpu, vn, i)
4816                                  << shift);
4817           else
4818             aarch64_set_vec_s64 (cpu, vd, i, aarch64_get_vec_s64 (cpu, vn, i)
4819                                  >> - shift);
4820         }
4821       return;
4822     }
4823 }
4824
4825 static void
4826 do_vec_USHL (sim_cpu *cpu)
4827 {
4828   /* instr[31]    = 0
4829      instr[30]    = first part (0)/ second part (1)
4830      instr[29,24] = 10 1110
4831      instr[23,22] = size: byte(00), half(01), word (10), long (11)
4832      instr[21]    = 1
4833      instr[20,16] = Vm
4834      instr[15,10] = 0100 01
4835      instr[9,5]   = Vn
4836      instr[4,0]   = Vd  */
4837
4838   unsigned full = INSTR (30, 30);
4839   unsigned vm = INSTR (20, 16);
4840   unsigned vn = INSTR (9, 5);
4841   unsigned vd = INSTR (4, 0);
4842   unsigned i;
4843   signed int shift;
4844
4845   NYI_assert (29, 24, 0x2E);
4846   NYI_assert (15, 10, 0x11);
4847
4848   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4849   switch (INSTR (23, 22))
4850     {
4851     case 0:
4852         for (i = 0; i < (full ? 16 : 8); i++)
4853           {
4854             shift = aarch64_get_vec_s8 (cpu, vm, i);
4855             if (shift >= 0)
4856               aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vn, i)
4857                                   << shift);
4858             else
4859               aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vn, i)
4860                                   >> - shift);
4861           }
4862       return;
4863
4864     case 1:
4865       for (i = 0; i < (full ? 8 : 4); i++)
4866         {
4867           shift = aarch64_get_vec_s8 (cpu, vm, i * 2);
4868           if (shift >= 0)
4869             aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vn, i)
4870                                  << shift);
4871           else
4872             aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vn, i)
4873                                  >> - shift);
4874         }
4875       return;
4876
4877     case 2:
4878       for (i = 0; i < (full ? 4 : 2); i++)
4879         {
4880           shift = aarch64_get_vec_s8 (cpu, vm, i * 4);
4881           if (shift >= 0)
4882             aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vn, i)
4883                                  << shift);
4884           else
4885             aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vn, i)
4886                                  >> - shift);
4887         }
4888       return;
4889
4890     case 3:
4891       if (! full)
4892         HALT_UNALLOC;
4893       for (i = 0; i < 2; i++)
4894         {
4895           shift = aarch64_get_vec_s8 (cpu, vm, i * 8);
4896           if (shift >= 0)
4897             aarch64_set_vec_u64 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vn, i)
4898                                  << shift);
4899           else
4900             aarch64_set_vec_u64 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vn, i)
4901                                  >> - shift);
4902         }
4903       return;
4904     }
4905 }
4906
4907 static void
4908 do_vec_FMLA (sim_cpu *cpu)
4909 {
4910   /* instr[31]    = 0
4911      instr[30]    = full/half selector
4912      instr[29,23] = 0011100
4913      instr[22]    = size: 0=>float, 1=>double
4914      instr[21]    = 1
4915      instr[20,16] = Vn
4916      instr[15,10] = 1100 11
4917      instr[9,5]   = Vm
4918      instr[4.0]   = Vd.  */
4919
4920   unsigned vm = INSTR (20, 16);
4921   unsigned vn = INSTR (9, 5);
4922   unsigned vd = INSTR (4, 0);
4923   unsigned i;
4924   int      full = INSTR (30, 30);
4925
4926   NYI_assert (29, 23, 0x1C);
4927   NYI_assert (21, 21, 1);
4928   NYI_assert (15, 10, 0x33);
4929
4930   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4931   if (INSTR (22, 22))
4932     {
4933       if (! full)
4934         HALT_UNALLOC;
4935       for (i = 0; i < 2; i++)
4936         aarch64_set_vec_double (cpu, vd, i,
4937                                 aarch64_get_vec_double (cpu, vn, i) *
4938                                 aarch64_get_vec_double (cpu, vm, i) +
4939                                 aarch64_get_vec_double (cpu, vd, i));
4940     }
4941   else
4942     {
4943       for (i = 0; i < (full ? 4 : 2); i++)
4944         aarch64_set_vec_float (cpu, vd, i,
4945                                aarch64_get_vec_float (cpu, vn, i) *
4946                                aarch64_get_vec_float (cpu, vm, i) +
4947                                aarch64_get_vec_float (cpu, vd, i));
4948     }
4949 }
4950
4951 static void
4952 do_vec_max (sim_cpu *cpu)
4953 {
4954   /* instr[31]    = 0
4955      instr[30]    = full/half selector
4956      instr[29]    = SMAX (0) / UMAX (1)
4957      instr[28,24] = 0 1110
4958      instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit
4959      instr[21]    = 1
4960      instr[20,16] = Vn
4961      instr[15,10] = 0110 01
4962      instr[9,5]   = Vm
4963      instr[4.0]   = Vd.  */
4964
4965   unsigned vm = INSTR (20, 16);
4966   unsigned vn = INSTR (9, 5);
4967   unsigned vd = INSTR (4, 0);
4968   unsigned i;
4969   int      full = INSTR (30, 30);
4970
4971   NYI_assert (28, 24, 0x0E);
4972   NYI_assert (21, 21, 1);
4973   NYI_assert (15, 10, 0x19);
4974
4975   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
4976   if (INSTR (29, 29))
4977     {
4978       switch (INSTR (23, 22))
4979         {
4980         case 0:
4981           for (i = 0; i < (full ? 16 : 8); i++)
4982             aarch64_set_vec_u8 (cpu, vd, i,
4983                                 aarch64_get_vec_u8 (cpu, vn, i)
4984                                 > aarch64_get_vec_u8 (cpu, vm, i)
4985                                 ? aarch64_get_vec_u8 (cpu, vn, i)
4986                                 : aarch64_get_vec_u8 (cpu, vm, i));
4987           return;
4988
4989         case 1:
4990           for (i = 0; i < (full ? 8 : 4); i++)
4991             aarch64_set_vec_u16 (cpu, vd, i,
4992                                  aarch64_get_vec_u16 (cpu, vn, i)
4993                                  > aarch64_get_vec_u16 (cpu, vm, i)
4994                                  ? aarch64_get_vec_u16 (cpu, vn, i)
4995                                  : aarch64_get_vec_u16 (cpu, vm, i));
4996           return;
4997
4998         case 2:
4999           for (i = 0; i < (full ? 4 : 2); i++)
5000             aarch64_set_vec_u32 (cpu, vd, i,
5001                                  aarch64_get_vec_u32 (cpu, vn, i)
5002                                  > aarch64_get_vec_u32 (cpu, vm, i)
5003                                  ? aarch64_get_vec_u32 (cpu, vn, i)
5004                                  : aarch64_get_vec_u32 (cpu, vm, i));
5005           return;
5006
5007         case 3:
5008           HALT_UNALLOC;
5009         }
5010     }
5011   else
5012     {
5013       switch (INSTR (23, 22))
5014         {
5015         case 0:
5016           for (i = 0; i < (full ? 16 : 8); i++)
5017             aarch64_set_vec_s8 (cpu, vd, i,
5018                                 aarch64_get_vec_s8 (cpu, vn, i)
5019                                 > aarch64_get_vec_s8 (cpu, vm, i)
5020                                 ? aarch64_get_vec_s8 (cpu, vn, i)
5021                                 : aarch64_get_vec_s8 (cpu, vm, i));
5022           return;
5023
5024         case 1:
5025           for (i = 0; i < (full ? 8 : 4); i++)
5026             aarch64_set_vec_s16 (cpu, vd, i,
5027                                  aarch64_get_vec_s16 (cpu, vn, i)
5028                                  > aarch64_get_vec_s16 (cpu, vm, i)
5029                                  ? aarch64_get_vec_s16 (cpu, vn, i)
5030                                  : aarch64_get_vec_s16 (cpu, vm, i));
5031           return;
5032
5033         case 2:
5034           for (i = 0; i < (full ? 4 : 2); i++)
5035             aarch64_set_vec_s32 (cpu, vd, i,
5036                                  aarch64_get_vec_s32 (cpu, vn, i)
5037                                  > aarch64_get_vec_s32 (cpu, vm, i)
5038                                  ? aarch64_get_vec_s32 (cpu, vn, i)
5039                                  : aarch64_get_vec_s32 (cpu, vm, i));
5040           return;
5041
5042         case 3:
5043           HALT_UNALLOC;
5044         }
5045     }
5046 }
5047
5048 static void
5049 do_vec_min (sim_cpu *cpu)
5050 {
5051   /* instr[31]    = 0
5052      instr[30]    = full/half selector
5053      instr[29]    = SMIN (0) / UMIN (1)
5054      instr[28,24] = 0 1110
5055      instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit
5056      instr[21]    = 1
5057      instr[20,16] = Vn
5058      instr[15,10] = 0110 11
5059      instr[9,5]   = Vm
5060      instr[4.0]   = Vd.  */
5061
5062   unsigned vm = INSTR (20, 16);
5063   unsigned vn = INSTR (9, 5);
5064   unsigned vd = INSTR (4, 0);
5065   unsigned i;
5066   int      full = INSTR (30, 30);
5067
5068   NYI_assert (28, 24, 0x0E);
5069   NYI_assert (21, 21, 1);
5070   NYI_assert (15, 10, 0x1B);
5071
5072   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5073   if (INSTR (29, 29))
5074     {
5075       switch (INSTR (23, 22))
5076         {
5077         case 0:
5078           for (i = 0; i < (full ? 16 : 8); i++)
5079             aarch64_set_vec_u8 (cpu, vd, i,
5080                                 aarch64_get_vec_u8 (cpu, vn, i)
5081                                 < aarch64_get_vec_u8 (cpu, vm, i)
5082                                 ? aarch64_get_vec_u8 (cpu, vn, i)
5083                                 : aarch64_get_vec_u8 (cpu, vm, i));
5084           return;
5085
5086         case 1:
5087           for (i = 0; i < (full ? 8 : 4); i++)
5088             aarch64_set_vec_u16 (cpu, vd, i,
5089                                  aarch64_get_vec_u16 (cpu, vn, i)
5090                                  < aarch64_get_vec_u16 (cpu, vm, i)
5091                                  ? aarch64_get_vec_u16 (cpu, vn, i)
5092                                  : aarch64_get_vec_u16 (cpu, vm, i));
5093           return;
5094
5095         case 2:
5096           for (i = 0; i < (full ? 4 : 2); i++)
5097             aarch64_set_vec_u32 (cpu, vd, i,
5098                                  aarch64_get_vec_u32 (cpu, vn, i)
5099                                  < aarch64_get_vec_u32 (cpu, vm, i)
5100                                  ? aarch64_get_vec_u32 (cpu, vn, i)
5101                                  : aarch64_get_vec_u32 (cpu, vm, i));
5102           return;
5103
5104         case 3:
5105           HALT_UNALLOC;
5106         }
5107     }
5108   else
5109     {
5110       switch (INSTR (23, 22))
5111         {
5112         case 0:
5113           for (i = 0; i < (full ? 16 : 8); i++)
5114             aarch64_set_vec_s8 (cpu, vd, i,
5115                                 aarch64_get_vec_s8 (cpu, vn, i)
5116                                 < aarch64_get_vec_s8 (cpu, vm, i)
5117                                 ? aarch64_get_vec_s8 (cpu, vn, i)
5118                                 : aarch64_get_vec_s8 (cpu, vm, i));
5119           return;
5120
5121         case 1:
5122           for (i = 0; i < (full ? 8 : 4); i++)
5123             aarch64_set_vec_s16 (cpu, vd, i,
5124                                  aarch64_get_vec_s16 (cpu, vn, i)
5125                                  < aarch64_get_vec_s16 (cpu, vm, i)
5126                                  ? aarch64_get_vec_s16 (cpu, vn, i)
5127                                  : aarch64_get_vec_s16 (cpu, vm, i));
5128           return;
5129
5130         case 2:
5131           for (i = 0; i < (full ? 4 : 2); i++)
5132             aarch64_set_vec_s32 (cpu, vd, i,
5133                                  aarch64_get_vec_s32 (cpu, vn, i)
5134                                  < aarch64_get_vec_s32 (cpu, vm, i)
5135                                  ? aarch64_get_vec_s32 (cpu, vn, i)
5136                                  : aarch64_get_vec_s32 (cpu, vm, i));
5137           return;
5138
5139         case 3:
5140           HALT_UNALLOC;
5141         }
5142     }
5143 }
5144
5145 static void
5146 do_vec_sub_long (sim_cpu *cpu)
5147 {
5148   /* instr[31]    = 0
5149      instr[30]    = lower (0) / upper (1)
5150      instr[29]    = signed (0) / unsigned (1)
5151      instr[28,24] = 0 1110
5152      instr[23,22] = size: bytes (00), half (01), word (10)
5153      instr[21]    = 1
5154      insrt[20,16] = Vm
5155      instr[15,10] = 0010 00
5156      instr[9,5]   = Vn
5157      instr[4,0]   = V dest.  */
5158
5159   unsigned size = INSTR (23, 22);
5160   unsigned vm = INSTR (20, 16);
5161   unsigned vn = INSTR (9, 5);
5162   unsigned vd = INSTR (4, 0);
5163   unsigned bias = 0;
5164   unsigned i;
5165
5166   NYI_assert (28, 24, 0x0E);
5167   NYI_assert (21, 21, 1);
5168   NYI_assert (15, 10, 0x08);
5169
5170   if (size == 3)
5171     HALT_UNALLOC;
5172
5173   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5174   switch (INSTR (30, 29))
5175     {
5176     case 2: /* SSUBL2.  */
5177       bias = 2;
5178     case 0: /* SSUBL.  */
5179       switch (size)
5180         {
5181         case 0:
5182           bias *= 3;
5183           for (i = 0; i < 8; i++)
5184             aarch64_set_vec_s16 (cpu, vd, i,
5185                                  aarch64_get_vec_s8 (cpu, vn, i + bias)
5186                                  - aarch64_get_vec_s8 (cpu, vm, i + bias));
5187           break;
5188
5189         case 1:
5190           bias *= 2;
5191           for (i = 0; i < 4; i++)
5192             aarch64_set_vec_s32 (cpu, vd, i,
5193                                  aarch64_get_vec_s16 (cpu, vn, i + bias)
5194                                  - aarch64_get_vec_s16 (cpu, vm, i + bias));
5195           break;
5196
5197         case 2:
5198           for (i = 0; i < 2; i++)
5199             aarch64_set_vec_s64 (cpu, vd, i,
5200                                  aarch64_get_vec_s32 (cpu, vn, i + bias)
5201                                  - aarch64_get_vec_s32 (cpu, vm, i + bias));
5202           break;
5203
5204         default:
5205           HALT_UNALLOC;
5206         }
5207       break;
5208
5209     case 3: /* USUBL2.  */
5210       bias = 2;
5211     case 1: /* USUBL.  */
5212       switch (size)
5213         {
5214         case 0:
5215           bias *= 3;
5216           for (i = 0; i < 8; i++)
5217             aarch64_set_vec_u16 (cpu, vd, i,
5218                                  aarch64_get_vec_u8 (cpu, vn, i + bias)
5219                                  - aarch64_get_vec_u8 (cpu, vm, i + bias));
5220           break;
5221
5222         case 1:
5223           bias *= 2;
5224           for (i = 0; i < 4; i++)
5225             aarch64_set_vec_u32 (cpu, vd, i,
5226                                  aarch64_get_vec_u16 (cpu, vn, i + bias)
5227                                  - aarch64_get_vec_u16 (cpu, vm, i + bias));
5228           break;
5229
5230         case 2:
5231           for (i = 0; i < 2; i++)
5232             aarch64_set_vec_u64 (cpu, vd, i,
5233                                  aarch64_get_vec_u32 (cpu, vn, i + bias)
5234                                  - aarch64_get_vec_u32 (cpu, vm, i + bias));
5235           break;
5236
5237         default:
5238           HALT_UNALLOC;
5239         }
5240       break;
5241     }
5242 }
5243
5244 static void
5245 do_vec_ADDP (sim_cpu *cpu)
5246 {
5247   /* instr[31]    = 0
5248      instr[30]    = half(0)/full(1)
5249      instr[29,24] = 00 1110
5250      instr[23,22] = size: bytes (00), half (01), word (10), long (11)
5251      instr[21]    = 1
5252      insrt[20,16] = Vm
5253      instr[15,10] = 1011 11
5254      instr[9,5]   = Vn
5255      instr[4,0]   = V dest.  */
5256
5257   FRegister copy_vn;
5258   FRegister copy_vm;
5259   unsigned full = INSTR (30, 30);
5260   unsigned size = INSTR (23, 22);
5261   unsigned vm = INSTR (20, 16);
5262   unsigned vn = INSTR (9, 5);
5263   unsigned vd = INSTR (4, 0);
5264   unsigned i, range;
5265
5266   NYI_assert (29, 24, 0x0E);
5267   NYI_assert (21, 21, 1);
5268   NYI_assert (15, 10, 0x2F);
5269
5270   /* Make copies of the source registers in case vd == vn/vm.  */
5271   copy_vn = cpu->fr[vn];
5272   copy_vm = cpu->fr[vm];
5273
5274   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5275   switch (size)
5276     {
5277     case 0:
5278       range = full ? 8 : 4;
5279       for (i = 0; i < range; i++)
5280         {
5281           aarch64_set_vec_u8 (cpu, vd, i,
5282                               copy_vn.b[i * 2] + copy_vn.b[i * 2 + 1]);
5283           aarch64_set_vec_u8 (cpu, vd, i + range,
5284                               copy_vm.b[i * 2] + copy_vm.b[i * 2 + 1]);
5285         }
5286       return;
5287
5288     case 1:
5289       range = full ? 4 : 2;
5290       for (i = 0; i < range; i++)
5291         {
5292           aarch64_set_vec_u16 (cpu, vd, i,
5293                                copy_vn.h[i * 2] + copy_vn.h[i * 2 + 1]);
5294           aarch64_set_vec_u16 (cpu, vd, i + range,
5295                                copy_vm.h[i * 2] + copy_vm.h[i * 2 + 1]);
5296         }
5297       return;
5298
5299     case 2:
5300       range = full ? 2 : 1;
5301       for (i = 0; i < range; i++)
5302         {
5303           aarch64_set_vec_u32 (cpu, vd, i,
5304                                copy_vn.w[i * 2] + copy_vn.w[i * 2 + 1]);
5305           aarch64_set_vec_u32 (cpu, vd, i + range,
5306                                copy_vm.w[i * 2] + copy_vm.w[i * 2 + 1]);
5307         }
5308       return;
5309
5310     case 3:
5311       if (! full)
5312         HALT_UNALLOC;
5313       aarch64_set_vec_u64 (cpu, vd, 0, copy_vn.v[0] + copy_vn.v[1]);
5314       aarch64_set_vec_u64 (cpu, vd, 1, copy_vm.v[0] + copy_vm.v[1]);
5315       return;
5316     }
5317 }
5318
5319 static void
5320 do_vec_UMOV (sim_cpu *cpu)
5321 {
5322   /* instr[31]    = 0
5323      instr[30]    = 32-bit(0)/64-bit(1)
5324      instr[29,21] = 00 1110 000
5325      insrt[20,16] = size & index
5326      instr[15,10] = 0011 11
5327      instr[9,5]   = V source
5328      instr[4,0]   = R dest.  */
5329
5330   unsigned vs = INSTR (9, 5);
5331   unsigned rd = INSTR (4, 0);
5332   unsigned index;
5333
5334   NYI_assert (29, 21, 0x070);
5335   NYI_assert (15, 10, 0x0F);
5336
5337   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5338   if (INSTR (16, 16))
5339     {
5340       /* Byte transfer.  */
5341       index = INSTR (20, 17);
5342       aarch64_set_reg_u64 (cpu, rd, NO_SP,
5343                            aarch64_get_vec_u8 (cpu, vs, index));
5344     }
5345   else if (INSTR (17, 17))
5346     {
5347       index = INSTR (20, 18);
5348       aarch64_set_reg_u64 (cpu, rd, NO_SP,
5349                            aarch64_get_vec_u16 (cpu, vs, index));
5350     }
5351   else if (INSTR (18, 18))
5352     {
5353       index = INSTR (20, 19);
5354       aarch64_set_reg_u64 (cpu, rd, NO_SP,
5355                            aarch64_get_vec_u32 (cpu, vs, index));
5356     }
5357   else
5358     {
5359       if (INSTR (30, 30) != 1)
5360         HALT_UNALLOC;
5361
5362       index = INSTR (20, 20);
5363       aarch64_set_reg_u64 (cpu, rd, NO_SP,
5364                            aarch64_get_vec_u64 (cpu, vs, index));
5365     }
5366 }
5367
5368 static void
5369 do_vec_FABS (sim_cpu *cpu)
5370 {
5371   /* instr[31]    = 0
5372      instr[30]    = half(0)/full(1)
5373      instr[29,23] = 00 1110 1
5374      instr[22]    = float(0)/double(1)
5375      instr[21,16] = 10 0000
5376      instr[15,10] = 1111 10
5377      instr[9,5]   = Vn
5378      instr[4,0]   = Vd.  */
5379
5380   unsigned vn = INSTR (9, 5);
5381   unsigned vd = INSTR (4, 0);
5382   unsigned full = INSTR (30, 30);
5383   unsigned i;
5384
5385   NYI_assert (29, 23, 0x1D);
5386   NYI_assert (21, 10, 0x83E);
5387
5388   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5389   if (INSTR (22, 22))
5390     {
5391       if (! full)
5392         HALT_NYI;
5393
5394       for (i = 0; i < 2; i++)
5395         aarch64_set_vec_double (cpu, vd, i,
5396                                 fabs (aarch64_get_vec_double (cpu, vn, i)));
5397     }
5398   else
5399     {
5400       for (i = 0; i < (full ? 4 : 2); i++)
5401         aarch64_set_vec_float (cpu, vd, i,
5402                                fabsf (aarch64_get_vec_float (cpu, vn, i)));
5403     }
5404 }
5405
5406 static void
5407 do_vec_FCVTZS (sim_cpu *cpu)
5408 {
5409   /* instr[31]    = 0
5410      instr[30]    = half (0) / all (1)
5411      instr[29,23] = 00 1110 1
5412      instr[22]    = single (0) / double (1)
5413      instr[21,10] = 10 0001 1011 10
5414      instr[9,5]   = Rn
5415      instr[4,0]   = Rd.  */
5416
5417   unsigned rn = INSTR (9, 5);
5418   unsigned rd = INSTR (4, 0);
5419   unsigned full = INSTR (30, 30);
5420   unsigned i;
5421
5422   NYI_assert (31, 31, 0);
5423   NYI_assert (29, 23, 0x1D);
5424   NYI_assert (21, 10, 0x86E);
5425
5426   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5427   if (INSTR (22, 22))
5428     {
5429       if (! full)
5430         HALT_UNALLOC;
5431
5432       for (i = 0; i < 2; i++)
5433         aarch64_set_vec_s64 (cpu, rd, i,
5434                              (int64_t) aarch64_get_vec_double (cpu, rn, i));
5435     }
5436   else
5437     for (i = 0; i < (full ? 4 : 2); i++)
5438       aarch64_set_vec_s32 (cpu, rd, i,
5439                            (int32_t) aarch64_get_vec_float (cpu, rn, i));
5440 }
5441
5442 static void
5443 do_vec_REV64 (sim_cpu *cpu)
5444 {
5445   /* instr[31]    = 0
5446      instr[30]    = full/half
5447      instr[29,24] = 00 1110 
5448      instr[23,22] = size
5449      instr[21,10] = 10 0000 0000 10
5450      instr[9,5]   = Rn
5451      instr[4,0]   = Rd.  */
5452
5453   unsigned rn = INSTR (9, 5);
5454   unsigned rd = INSTR (4, 0);
5455   unsigned size = INSTR (23, 22);
5456   unsigned full = INSTR (30, 30);
5457   unsigned i;
5458   FRegister val;
5459
5460   NYI_assert (29, 24, 0x0E);
5461   NYI_assert (21, 10, 0x802);
5462
5463   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5464   switch (size)
5465     {
5466     case 0:
5467       for (i = 0; i < (full ? 16 : 8); i++)
5468         val.b[i ^ 0x7] = aarch64_get_vec_u8 (cpu, rn, i);
5469       break;
5470
5471     case 1:
5472       for (i = 0; i < (full ? 8 : 4); i++)
5473         val.h[i ^ 0x3] = aarch64_get_vec_u16 (cpu, rn, i);
5474       break;
5475
5476     case 2:
5477       for (i = 0; i < (full ? 4 : 2); i++)
5478         val.w[i ^ 0x1] = aarch64_get_vec_u32 (cpu, rn, i);
5479       break;
5480       
5481     case 3:
5482       HALT_UNALLOC;
5483     }
5484
5485   aarch64_set_vec_u64 (cpu, rd, 0, val.v[0]);
5486   if (full)
5487     aarch64_set_vec_u64 (cpu, rd, 1, val.v[1]);
5488 }
5489
5490 static void
5491 do_vec_REV16 (sim_cpu *cpu)
5492 {
5493   /* instr[31]    = 0
5494      instr[30]    = full/half
5495      instr[29,24] = 00 1110 
5496      instr[23,22] = size
5497      instr[21,10] = 10 0000 0001 10
5498      instr[9,5]   = Rn
5499      instr[4,0]   = Rd.  */
5500
5501   unsigned rn = INSTR (9, 5);
5502   unsigned rd = INSTR (4, 0);
5503   unsigned size = INSTR (23, 22);
5504   unsigned full = INSTR (30, 30);
5505   unsigned i;
5506   FRegister val;
5507
5508   NYI_assert (29, 24, 0x0E);
5509   NYI_assert (21, 10, 0x806);
5510
5511   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5512   switch (size)
5513     {
5514     case 0:
5515       for (i = 0; i < (full ? 16 : 8); i++)
5516         val.b[i ^ 0x1] = aarch64_get_vec_u8 (cpu, rn, i);
5517       break;
5518
5519     default:
5520       HALT_UNALLOC;
5521     }
5522
5523   aarch64_set_vec_u64 (cpu, rd, 0, val.v[0]);
5524   if (full)
5525     aarch64_set_vec_u64 (cpu, rd, 1, val.v[1]);
5526 }
5527
5528 static void
5529 do_vec_op1 (sim_cpu *cpu)
5530 {
5531   /* instr[31]    = 0
5532      instr[30]    = half/full
5533      instr[29,24] = 00 1110
5534      instr[23,21] = ???
5535      instr[20,16] = Vm
5536      instr[15,10] = sub-opcode
5537      instr[9,5]   = Vn
5538      instr[4,0]   = Vd  */
5539   NYI_assert (29, 24, 0x0E);
5540
5541   if (INSTR (21, 21) == 0)
5542     {
5543       if (INSTR (23, 22) == 0)
5544         {
5545           if (INSTR (30, 30) == 1
5546               && INSTR (17, 14) == 0
5547               && INSTR (12, 10) == 7)
5548             return do_vec_ins_2 (cpu);
5549
5550           switch (INSTR (15, 10))
5551             {
5552             case 0x01: do_vec_DUP_vector_into_vector (cpu); return;
5553             case 0x03: do_vec_DUP_scalar_into_vector (cpu); return;
5554             case 0x07: do_vec_INS (cpu); return;
5555             case 0x0A: do_vec_TRN (cpu); return;
5556
5557             case 0x0F:
5558               if (INSTR (17, 16) == 0)
5559                 {
5560                   do_vec_MOV_into_scalar (cpu);
5561                   return;
5562                 }
5563               break;
5564
5565             case 0x00:
5566             case 0x08:
5567             case 0x10:
5568             case 0x18:
5569               do_vec_TBL (cpu); return;
5570
5571             case 0x06:
5572             case 0x16:
5573               do_vec_UZP (cpu); return;
5574
5575             case 0x0E:
5576             case 0x1E:
5577               do_vec_ZIP (cpu); return;
5578
5579             default:
5580               HALT_NYI;
5581             }
5582         }
5583
5584       switch (INSTR (13, 10))
5585         {
5586         case 0x6: do_vec_UZP (cpu); return;
5587         case 0xE: do_vec_ZIP (cpu); return;
5588         case 0xA: do_vec_TRN (cpu); return;
5589         case 0xF: do_vec_UMOV (cpu); return;
5590         default:  HALT_NYI;
5591         }
5592     }
5593
5594   switch (INSTR (15, 10))
5595     {
5596     case 0x02: do_vec_REV64 (cpu); return;
5597     case 0x06: do_vec_REV16 (cpu); return;
5598
5599     case 0x07:
5600       switch (INSTR (23, 21))
5601         {
5602         case 1: do_vec_AND (cpu); return;
5603         case 3: do_vec_BIC (cpu); return;
5604         case 5: do_vec_ORR (cpu); return;
5605         case 7: do_vec_ORN (cpu); return;
5606         default: HALT_NYI;
5607         }
5608
5609     case 0x08: do_vec_sub_long (cpu); return;
5610     case 0x0a: do_vec_XTN (cpu); return;
5611     case 0x11: do_vec_SSHL (cpu); return;
5612     case 0x19: do_vec_max (cpu); return;
5613     case 0x1B: do_vec_min (cpu); return;
5614     case 0x21: do_vec_add (cpu); return;
5615     case 0x25: do_vec_MLA (cpu); return;
5616     case 0x27: do_vec_mul (cpu); return;
5617     case 0x2F: do_vec_ADDP (cpu); return;
5618     case 0x30: do_vec_mull (cpu); return;
5619     case 0x33: do_vec_FMLA (cpu); return;
5620     case 0x35: do_vec_fadd (cpu); return;
5621
5622     case 0x2E:
5623       switch (INSTR (20, 16))
5624         {
5625         case 0x00: do_vec_ABS (cpu); return;
5626         case 0x01: do_vec_FCVTZS (cpu); return;
5627         case 0x11: do_vec_ADDV (cpu); return;
5628         default: HALT_NYI;
5629         }
5630
5631     case 0x31:
5632     case 0x3B:
5633       do_vec_Fminmax (cpu); return;
5634
5635     case 0x0D:
5636     case 0x0F:
5637     case 0x22:
5638     case 0x23:
5639     case 0x26:
5640     case 0x2A:
5641     case 0x32:
5642     case 0x36:
5643     case 0x39:
5644     case 0x3A:
5645       do_vec_compare (cpu); return;
5646
5647     case 0x3E:
5648       do_vec_FABS (cpu); return;
5649
5650     default:
5651       HALT_NYI;
5652     }
5653 }
5654
5655 static void
5656 do_vec_xtl (sim_cpu *cpu)
5657 {
5658   /* instr[31]    = 0
5659      instr[30,29] = SXTL (00), UXTL (01), SXTL2 (10), UXTL2 (11)
5660      instr[28,22] = 0 1111 00
5661      instr[21,16] = size & shift (USHLL, SSHLL, USHLL2, SSHLL2)
5662      instr[15,10] = 1010 01
5663      instr[9,5]   = V source
5664      instr[4,0]   = V dest.  */
5665
5666   unsigned vs = INSTR (9, 5);
5667   unsigned vd = INSTR (4, 0);
5668   unsigned i, shift, bias = 0;
5669
5670   NYI_assert (28, 22, 0x3C);
5671   NYI_assert (15, 10, 0x29);
5672
5673   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5674   switch (INSTR (30, 29))
5675     {
5676     case 2: /* SXTL2, SSHLL2.  */
5677       bias = 2;
5678     case 0: /* SXTL, SSHLL.  */
5679       if (INSTR (21, 21))
5680         {
5681           int64_t val1, val2;
5682
5683           shift = INSTR (20, 16);
5684           /* Get the source values before setting the destination values
5685              in case the source and destination are the same.  */
5686           val1 = aarch64_get_vec_s32 (cpu, vs, bias) << shift;
5687           val2 = aarch64_get_vec_s32 (cpu, vs, bias + 1) << shift;
5688           aarch64_set_vec_s64 (cpu, vd, 0, val1);
5689           aarch64_set_vec_s64 (cpu, vd, 1, val2);
5690         }
5691       else if (INSTR (20, 20))
5692         {
5693           int32_t v[4];
5694           int32_t v1,v2,v3,v4;
5695
5696           shift = INSTR (19, 16);
5697           bias *= 2;
5698           for (i = 0; i < 4; i++)
5699             v[i] = aarch64_get_vec_s16 (cpu, vs, bias + i) << shift;
5700           for (i = 0; i < 4; i++)
5701             aarch64_set_vec_s32 (cpu, vd, i, v[i]);
5702         }
5703       else
5704         {
5705           int16_t v[8];
5706           NYI_assert (19, 19, 1);
5707
5708           shift = INSTR (18, 16);
5709           bias *= 3;
5710           for (i = 0; i < 8; i++)
5711             v[i] = aarch64_get_vec_s8 (cpu, vs, i + bias) << shift;
5712           for (i = 0; i < 8; i++)
5713             aarch64_set_vec_s16 (cpu, vd, i, v[i]);
5714         }
5715       return;
5716
5717     case 3: /* UXTL2, USHLL2.  */
5718       bias = 2;
5719     case 1: /* UXTL, USHLL.  */
5720       if (INSTR (21, 21))
5721         {
5722           uint64_t v1, v2;
5723           shift = INSTR (20, 16);
5724           v1 = aarch64_get_vec_u32 (cpu, vs, bias) << shift;
5725           v2 = aarch64_get_vec_u32 (cpu, vs, bias + 1) << shift;
5726           aarch64_set_vec_u64 (cpu, vd, 0, v1);
5727           aarch64_set_vec_u64 (cpu, vd, 1, v2);
5728         }
5729       else if (INSTR (20, 20))
5730         {
5731           uint32_t v[4];
5732           shift = INSTR (19, 16);
5733           bias *= 2;
5734           for (i = 0; i < 4; i++)
5735             v[i] = aarch64_get_vec_u16 (cpu, vs, i + bias) << shift;
5736           for (i = 0; i < 4; i++)
5737             aarch64_set_vec_u32 (cpu, vd, i, v[i]);
5738         }
5739       else
5740         {
5741           uint16_t v[8];
5742           NYI_assert (19, 19, 1);
5743
5744           shift = INSTR (18, 16);
5745           bias *= 3;
5746           for (i = 0; i < 8; i++)
5747             v[i] = aarch64_get_vec_u8 (cpu, vs, i + bias) << shift;
5748           for (i = 0; i < 8; i++)
5749             aarch64_set_vec_u16 (cpu, vd, i, v[i]);
5750         }
5751       return;
5752     }
5753 }
5754
5755 static void
5756 do_vec_SHL (sim_cpu *cpu)
5757 {
5758   /* instr [31]    = 0
5759      instr [30]    = half(0)/full(1)
5760      instr [29,23] = 001 1110
5761      instr [22,16] = size and shift amount
5762      instr [15,10] = 01 0101
5763      instr [9, 5]  = Vs
5764      instr [4, 0]  = Vd.  */
5765
5766   int shift;
5767   int full    = INSTR (30, 30);
5768   unsigned vs = INSTR (9, 5);
5769   unsigned vd = INSTR (4, 0);
5770   unsigned i;
5771
5772   NYI_assert (29, 23, 0x1E);
5773   NYI_assert (15, 10, 0x15);
5774
5775   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5776   if (INSTR (22, 22))
5777     {
5778       shift = INSTR (21, 16);
5779
5780       if (full == 0)
5781         HALT_UNALLOC;
5782
5783       for (i = 0; i < 2; i++)
5784         {
5785           uint64_t val = aarch64_get_vec_u64 (cpu, vs, i);
5786           aarch64_set_vec_u64 (cpu, vd, i, val << shift);
5787         }
5788
5789       return;
5790     }
5791
5792   if (INSTR (21, 21))
5793     {
5794       shift = INSTR (20, 16);
5795
5796       for (i = 0; i < (full ? 4 : 2); i++)
5797         {
5798           uint32_t val = aarch64_get_vec_u32 (cpu, vs, i);
5799           aarch64_set_vec_u32 (cpu, vd, i, val << shift);
5800         }
5801
5802       return;
5803     }
5804
5805   if (INSTR (20, 20))
5806     {
5807       shift = INSTR (19, 16);
5808
5809       for (i = 0; i < (full ? 8 : 4); i++)
5810         {
5811           uint16_t val = aarch64_get_vec_u16 (cpu, vs, i);
5812           aarch64_set_vec_u16 (cpu, vd, i, val << shift);
5813         }
5814
5815       return;
5816     }
5817
5818   if (INSTR (19, 19) == 0)
5819     HALT_UNALLOC;
5820
5821   shift = INSTR (18, 16);
5822
5823   for (i = 0; i < (full ? 16 : 8); i++)
5824     {
5825       uint8_t val = aarch64_get_vec_u8 (cpu, vs, i);
5826       aarch64_set_vec_u8 (cpu, vd, i, val << shift);
5827     }
5828 }
5829
5830 static void
5831 do_vec_SSHR_USHR (sim_cpu *cpu)
5832 {
5833   /* instr [31]    = 0
5834      instr [30]    = half(0)/full(1)
5835      instr [29]    = signed(0)/unsigned(1)
5836      instr [28,23] = 0 1111 0
5837      instr [22,16] = size and shift amount
5838      instr [15,10] = 0000 01
5839      instr [9, 5]  = Vs
5840      instr [4, 0]  = Vd.  */
5841
5842   int full       = INSTR (30, 30);
5843   int sign       = ! INSTR (29, 29);
5844   unsigned shift = INSTR (22, 16);
5845   unsigned vs    = INSTR (9, 5);
5846   unsigned vd    = INSTR (4, 0);
5847   unsigned i;
5848
5849   NYI_assert (28, 23, 0x1E);
5850   NYI_assert (15, 10, 0x01);
5851
5852   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5853   if (INSTR (22, 22))
5854     {
5855       shift = 128 - shift;
5856
5857       if (full == 0)
5858         HALT_UNALLOC;
5859
5860       if (sign)
5861         for (i = 0; i < 2; i++)
5862           {
5863             int64_t val = aarch64_get_vec_s64 (cpu, vs, i);
5864             aarch64_set_vec_s64 (cpu, vd, i, val >> shift);
5865           }
5866       else
5867         for (i = 0; i < 2; i++)
5868           {
5869             uint64_t val = aarch64_get_vec_u64 (cpu, vs, i);
5870             aarch64_set_vec_u64 (cpu, vd, i, val >> shift);
5871           }
5872
5873       return;
5874     }
5875
5876   if (INSTR (21, 21))
5877     {
5878       shift = 64 - shift;
5879
5880       if (sign)
5881         for (i = 0; i < (full ? 4 : 2); i++)
5882           {
5883             int32_t val = aarch64_get_vec_s32 (cpu, vs, i);
5884             aarch64_set_vec_s32 (cpu, vd, i, val >> shift);
5885           }
5886       else
5887         for (i = 0; i < (full ? 4 : 2); i++)
5888           {
5889             uint32_t val = aarch64_get_vec_u32 (cpu, vs, i);
5890             aarch64_set_vec_u32 (cpu, vd, i, val >> shift);
5891           }
5892
5893       return;
5894     }
5895
5896   if (INSTR (20, 20))
5897     {
5898       shift = 32 - shift;
5899
5900       if (sign)
5901         for (i = 0; i < (full ? 8 : 4); i++)
5902           {
5903             int16_t val = aarch64_get_vec_s16 (cpu, vs, i);
5904             aarch64_set_vec_s16 (cpu, vd, i, val >> shift);
5905           }
5906       else
5907         for (i = 0; i < (full ? 8 : 4); i++)
5908           {
5909             uint16_t val = aarch64_get_vec_u16 (cpu, vs, i);
5910             aarch64_set_vec_u16 (cpu, vd, i, val >> shift);
5911           }
5912
5913       return;
5914     }
5915
5916   if (INSTR (19, 19) == 0)
5917     HALT_UNALLOC;
5918
5919   shift = 16 - shift;
5920
5921   if (sign)
5922     for (i = 0; i < (full ? 16 : 8); i++)
5923       {
5924         int8_t val = aarch64_get_vec_s8 (cpu, vs, i);
5925         aarch64_set_vec_s8 (cpu, vd, i, val >> shift);
5926       }
5927   else
5928     for (i = 0; i < (full ? 16 : 8); i++)
5929       {
5930         uint8_t val = aarch64_get_vec_u8 (cpu, vs, i);
5931         aarch64_set_vec_u8 (cpu, vd, i, val >> shift);
5932       }
5933 }
5934
5935 static void
5936 do_vec_MUL_by_element (sim_cpu *cpu)
5937 {
5938   /* instr[31]    = 0
5939      instr[30]    = half/full
5940      instr[29,24] = 00 1111
5941      instr[23,22] = size
5942      instr[21]    = L
5943      instr[20]    = M
5944      instr[19,16] = m
5945      instr[15,12] = 1000
5946      instr[11]    = H
5947      instr[10]    = 0
5948      instr[9,5]   = Vn
5949      instr[4,0]   = Vd  */
5950
5951   unsigned full     = INSTR (30, 30);
5952   unsigned L        = INSTR (21, 21);
5953   unsigned H        = INSTR (11, 11);
5954   unsigned vn       = INSTR (9, 5);
5955   unsigned vd       = INSTR (4, 0);
5956   unsigned size     = INSTR (23, 22);
5957   unsigned index;
5958   unsigned vm;
5959   unsigned e;
5960
5961   NYI_assert (29, 24, 0x0F);
5962   NYI_assert (15, 12, 0x8);
5963   NYI_assert (10, 10, 0);
5964
5965   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
5966   switch (size)
5967     {
5968     case 1:
5969       {
5970         /* 16 bit products.  */
5971         uint16_t product;
5972         uint16_t element1;
5973         uint16_t element2;
5974
5975         index = (H << 2) | (L << 1) | INSTR (20, 20);
5976         vm = INSTR (19, 16);
5977         element2 = aarch64_get_vec_u16 (cpu, vm, index);
5978
5979         for (e = 0; e < (full ? 8 : 4); e ++)
5980           {
5981             element1 = aarch64_get_vec_u16 (cpu, vn, e);
5982             product  = element1 * element2;
5983             aarch64_set_vec_u16 (cpu, vd, e, product);
5984           }
5985       }
5986       break;
5987
5988     case 2:
5989       {
5990         /* 32 bit products.  */
5991         uint32_t product;
5992         uint32_t element1;
5993         uint32_t element2;
5994
5995         index = (H << 1) | L;
5996         vm = INSTR (20, 16);
5997         element2 = aarch64_get_vec_u32 (cpu, vm, index);
5998
5999         for (e = 0; e < (full ? 4 : 2); e ++)
6000           {
6001             element1 = aarch64_get_vec_u32 (cpu, vn, e);
6002             product  = element1 * element2;
6003             aarch64_set_vec_u32 (cpu, vd, e, product);
6004           }
6005       }
6006       break;
6007
6008     default:
6009       HALT_UNALLOC;
6010     }
6011 }
6012
6013 static void
6014 do_FMLA_by_element (sim_cpu *cpu)
6015 {
6016   /* instr[31]    = 0
6017      instr[30]    = half/full
6018      instr[29,23] = 00 1111 1
6019      instr[22]    = size
6020      instr[21]    = L
6021      instr[20,16] = m
6022      instr[15,12] = 0001
6023      instr[11]    = H
6024      instr[10]    = 0
6025      instr[9,5]   = Vn
6026      instr[4,0]   = Vd  */
6027
6028   unsigned full     = INSTR (30, 30);
6029   unsigned size     = INSTR (22, 22);
6030   unsigned L        = INSTR (21, 21);
6031   unsigned vm       = INSTR (20, 16);
6032   unsigned H        = INSTR (11, 11);
6033   unsigned vn       = INSTR (9, 5);
6034   unsigned vd       = INSTR (4, 0);
6035   unsigned e;
6036
6037   NYI_assert (29, 23, 0x1F);
6038   NYI_assert (15, 12, 0x1);
6039   NYI_assert (10, 10, 0);
6040
6041   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6042   if (size)
6043     {
6044       double element1, element2;
6045
6046       if (! full || L)
6047         HALT_UNALLOC;
6048
6049       element2 = aarch64_get_vec_double (cpu, vm, H);
6050
6051       for (e = 0; e < 2; e++)
6052         {
6053           element1 = aarch64_get_vec_double (cpu, vn, e);
6054           element1 *= element2;
6055           element1 += aarch64_get_vec_double (cpu, vd, e);
6056           aarch64_set_vec_double (cpu, vd, e, element1);
6057         }
6058     }
6059   else
6060     {
6061       float element1;
6062       float element2 = aarch64_get_vec_float (cpu, vm, (H << 1) | L);
6063
6064       for (e = 0; e < (full ? 4 : 2); e++)
6065         {
6066           element1 = aarch64_get_vec_float (cpu, vn, e);
6067           element1 *= element2;
6068           element1 += aarch64_get_vec_float (cpu, vd, e);
6069           aarch64_set_vec_float (cpu, vd, e, element1);
6070         }
6071     }
6072 }
6073
6074 static void
6075 do_vec_op2 (sim_cpu *cpu)
6076 {
6077   /* instr[31]    = 0
6078      instr[30]    = half/full
6079      instr[29,24] = 00 1111
6080      instr[23]    = ?
6081      instr[22,16] = element size & index
6082      instr[15,10] = sub-opcode
6083      instr[9,5]   = Vm
6084      instr[4,0]   = Vd  */
6085
6086   NYI_assert (29, 24, 0x0F);
6087
6088   if (INSTR (23, 23) != 0)
6089     {
6090       switch (INSTR (15, 10))
6091         {
6092         case 0x04:
6093         case 0x06:
6094           do_FMLA_by_element (cpu);
6095           return;
6096
6097         case 0x20:
6098         case 0x22:
6099           do_vec_MUL_by_element (cpu);
6100           return;
6101
6102         default:
6103           HALT_NYI;
6104         }
6105     }
6106   else
6107     {
6108       switch (INSTR (15, 10))
6109         {
6110         case 0x01: do_vec_SSHR_USHR (cpu); return;
6111         case 0x15: do_vec_SHL (cpu); return;
6112         case 0x20:
6113         case 0x22: do_vec_MUL_by_element (cpu); return;
6114         case 0x29: do_vec_xtl (cpu); return;
6115         default:   HALT_NYI;
6116         }
6117     }
6118 }
6119
6120 static void
6121 do_vec_neg (sim_cpu *cpu)
6122 {
6123   /* instr[31]    = 0
6124      instr[30]    = full(1)/half(0)
6125      instr[29,24] = 10 1110
6126      instr[23,22] = size: byte(00), half (01), word (10), long (11)
6127      instr[21,10] = 1000 0010 1110
6128      instr[9,5]   = Vs
6129      instr[4,0]   = Vd  */
6130
6131   int    full = INSTR (30, 30);
6132   unsigned vs = INSTR (9, 5);
6133   unsigned vd = INSTR (4, 0);
6134   unsigned i;
6135
6136   NYI_assert (29, 24, 0x2E);
6137   NYI_assert (21, 10, 0x82E);
6138
6139   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6140   switch (INSTR (23, 22))
6141     {
6142     case 0:
6143       for (i = 0; i < (full ? 16 : 8); i++)
6144         aarch64_set_vec_s8 (cpu, vd, i, - aarch64_get_vec_s8 (cpu, vs, i));
6145       return;
6146
6147     case 1:
6148       for (i = 0; i < (full ? 8 : 4); i++)
6149         aarch64_set_vec_s16 (cpu, vd, i, - aarch64_get_vec_s16 (cpu, vs, i));
6150       return;
6151
6152     case 2:
6153       for (i = 0; i < (full ? 4 : 2); i++)
6154         aarch64_set_vec_s32 (cpu, vd, i, - aarch64_get_vec_s32 (cpu, vs, i));
6155       return;
6156
6157     case 3:
6158       if (! full)
6159         HALT_NYI;
6160       for (i = 0; i < 2; i++)
6161         aarch64_set_vec_s64 (cpu, vd, i, - aarch64_get_vec_s64 (cpu, vs, i));
6162       return;
6163     }
6164 }
6165
6166 static void
6167 do_vec_sqrt (sim_cpu *cpu)
6168 {
6169   /* instr[31]    = 0
6170      instr[30]    = full(1)/half(0)
6171      instr[29,23] = 101 1101
6172      instr[22]    = single(0)/double(1)
6173      instr[21,10] = 1000 0111 1110
6174      instr[9,5]   = Vs
6175      instr[4,0]   = Vd.  */
6176
6177   int    full = INSTR (30, 30);
6178   unsigned vs = INSTR (9, 5);
6179   unsigned vd = INSTR (4, 0);
6180   unsigned i;
6181
6182   NYI_assert (29, 23, 0x5B);
6183   NYI_assert (21, 10, 0x87E);
6184
6185   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6186   if (INSTR (22, 22) == 0)
6187     for (i = 0; i < (full ? 4 : 2); i++)
6188       aarch64_set_vec_float (cpu, vd, i,
6189                              sqrtf (aarch64_get_vec_float (cpu, vs, i)));
6190   else
6191     for (i = 0; i < 2; i++)
6192       aarch64_set_vec_double (cpu, vd, i,
6193                               sqrt (aarch64_get_vec_double (cpu, vs, i)));
6194 }
6195
6196 static void
6197 do_vec_mls_indexed (sim_cpu *cpu)
6198 {
6199   /* instr[31]       = 0
6200      instr[30]       = half(0)/full(1)
6201      instr[29,24]    = 10 1111
6202      instr[23,22]    = 16-bit(01)/32-bit(10)
6203      instr[21,20+11] = index (if 16-bit)
6204      instr[21+11]    = index (if 32-bit)
6205      instr[20,16]    = Vm
6206      instr[15,12]    = 0100
6207      instr[11]       = part of index
6208      instr[10]       = 0
6209      instr[9,5]      = Vs
6210      instr[4,0]      = Vd.  */
6211
6212   int    full = INSTR (30, 30);
6213   unsigned vs = INSTR (9, 5);
6214   unsigned vd = INSTR (4, 0);
6215   unsigned vm = INSTR (20, 16);
6216   unsigned i;
6217
6218   NYI_assert (15, 12, 4);
6219   NYI_assert (10, 10, 0);
6220
6221   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6222   switch (INSTR (23, 22))
6223     {
6224     case 1:
6225       {
6226         unsigned elem;
6227         uint32_t val;
6228
6229         if (vm > 15)
6230           HALT_NYI;
6231
6232         elem = (INSTR (21, 20) << 1) | INSTR (11, 11);
6233         val = aarch64_get_vec_u16 (cpu, vm, elem);
6234
6235         for (i = 0; i < (full ? 8 : 4); i++)
6236           aarch64_set_vec_u32 (cpu, vd, i,
6237                                aarch64_get_vec_u32 (cpu, vd, i) -
6238                                (aarch64_get_vec_u32 (cpu, vs, i) * val));
6239         return;
6240       }
6241
6242     case 2:
6243       {
6244         unsigned elem = (INSTR (21, 21) << 1) | INSTR (11, 11);
6245         uint64_t val = aarch64_get_vec_u32 (cpu, vm, elem);
6246
6247         for (i = 0; i < (full ? 4 : 2); i++)
6248           aarch64_set_vec_u64 (cpu, vd, i,
6249                                aarch64_get_vec_u64 (cpu, vd, i) -
6250                                (aarch64_get_vec_u64 (cpu, vs, i) * val));
6251         return;
6252       }
6253
6254     case 0:
6255     case 3:
6256     default:
6257       HALT_NYI;
6258     }
6259 }
6260
6261 static void
6262 do_vec_SUB (sim_cpu *cpu)
6263 {
6264   /* instr [31]    = 0
6265      instr [30]    = half(0)/full(1)
6266      instr [29,24] = 10 1110
6267      instr [23,22] = size: byte(00, half(01), word (10), long (11)
6268      instr [21]    = 1
6269      instr [20,16] = Vm
6270      instr [15,10] = 10 0001
6271      instr [9, 5]  = Vn
6272      instr [4, 0]  = Vd.  */
6273
6274   unsigned full = INSTR (30, 30);
6275   unsigned vm = INSTR (20, 16);
6276   unsigned vn = INSTR (9, 5);
6277   unsigned vd = INSTR (4, 0);
6278   unsigned i;
6279
6280   NYI_assert (29, 24, 0x2E);
6281   NYI_assert (21, 21, 1);
6282   NYI_assert (15, 10, 0x21);
6283
6284   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6285   switch (INSTR (23, 22))
6286     {
6287     case 0:
6288       for (i = 0; i < (full ? 16 : 8); i++)
6289         aarch64_set_vec_s8 (cpu, vd, i,
6290                             aarch64_get_vec_s8 (cpu, vn, i)
6291                             - aarch64_get_vec_s8 (cpu, vm, i));
6292       return;
6293
6294     case 1:
6295       for (i = 0; i < (full ? 8 : 4); i++)
6296         aarch64_set_vec_s16 (cpu, vd, i,
6297                              aarch64_get_vec_s16 (cpu, vn, i)
6298                              - aarch64_get_vec_s16 (cpu, vm, i));
6299       return;
6300
6301     case 2:
6302       for (i = 0; i < (full ? 4 : 2); i++)
6303         aarch64_set_vec_s32 (cpu, vd, i,
6304                              aarch64_get_vec_s32 (cpu, vn, i)
6305                              - aarch64_get_vec_s32 (cpu, vm, i));
6306       return;
6307
6308     case 3:
6309       if (full == 0)
6310         HALT_UNALLOC;
6311
6312       for (i = 0; i < 2; i++)
6313         aarch64_set_vec_s64 (cpu, vd, i,
6314                              aarch64_get_vec_s64 (cpu, vn, i)
6315                              - aarch64_get_vec_s64 (cpu, vm, i));
6316       return;
6317     }
6318 }
6319
6320 static void
6321 do_vec_MLS (sim_cpu *cpu)
6322 {
6323   /* instr [31]    = 0
6324      instr [30]    = half(0)/full(1)
6325      instr [29,24] = 10 1110
6326      instr [23,22] = size: byte(00, half(01), word (10)
6327      instr [21]    = 1
6328      instr [20,16] = Vm
6329      instr [15,10] = 10 0101
6330      instr [9, 5]  = Vn
6331      instr [4, 0]  = Vd.  */
6332
6333   unsigned full = INSTR (30, 30);
6334   unsigned vm = INSTR (20, 16);
6335   unsigned vn = INSTR (9, 5);
6336   unsigned vd = INSTR (4, 0);
6337   unsigned i;
6338
6339   NYI_assert (29, 24, 0x2E);
6340   NYI_assert (21, 21, 1);
6341   NYI_assert (15, 10, 0x25);
6342
6343   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6344   switch (INSTR (23, 22))
6345     {
6346     case 0:
6347       for (i = 0; i < (full ? 16 : 8); i++)
6348         aarch64_set_vec_u8 (cpu, vd, i,
6349                             (aarch64_get_vec_u8 (cpu, vn, i)
6350                              * aarch64_get_vec_u8 (cpu, vm, i))
6351                             - aarch64_get_vec_u8 (cpu, vd, i));
6352       return;
6353
6354     case 1:
6355       for (i = 0; i < (full ? 8 : 4); i++)
6356         aarch64_set_vec_u16 (cpu, vd, i,
6357                              (aarch64_get_vec_u16 (cpu, vn, i)
6358                               * aarch64_get_vec_u16 (cpu, vm, i))
6359                              - aarch64_get_vec_u16 (cpu, vd, i));
6360       return;
6361
6362     case 2:
6363       for (i = 0; i < (full ? 4 : 2); i++)
6364         aarch64_set_vec_u32 (cpu, vd, i,
6365                              (aarch64_get_vec_u32 (cpu, vn, i)
6366                               * aarch64_get_vec_u32 (cpu, vm, i))
6367                              - aarch64_get_vec_u32 (cpu, vd, i));
6368       return;
6369
6370     default:
6371       HALT_UNALLOC;
6372     }
6373 }
6374
6375 static void
6376 do_vec_FDIV (sim_cpu *cpu)
6377 {
6378   /* instr [31]    = 0
6379      instr [30]    = half(0)/full(1)
6380      instr [29,23] = 10 1110 0
6381      instr [22]    = float()/double(1)
6382      instr [21]    = 1
6383      instr [20,16] = Vm
6384      instr [15,10] = 1111 11
6385      instr [9, 5]  = Vn
6386      instr [4, 0]  = Vd.  */
6387
6388   unsigned full = INSTR (30, 30);
6389   unsigned vm = INSTR (20, 16);
6390   unsigned vn = INSTR (9, 5);
6391   unsigned vd = INSTR (4, 0);
6392   unsigned i;
6393
6394   NYI_assert (29, 23, 0x5C);
6395   NYI_assert (21, 21, 1);
6396   NYI_assert (15, 10, 0x3F);
6397
6398   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6399   if (INSTR (22, 22))
6400     {
6401       if (! full)
6402         HALT_UNALLOC;
6403
6404       for (i = 0; i < 2; i++)
6405         aarch64_set_vec_double (cpu, vd, i,
6406                                 aarch64_get_vec_double (cpu, vn, i)
6407                                 / aarch64_get_vec_double (cpu, vm, i));
6408     }
6409   else
6410     for (i = 0; i < (full ? 4 : 2); i++)
6411       aarch64_set_vec_float (cpu, vd, i,
6412                              aarch64_get_vec_float (cpu, vn, i)
6413                              / aarch64_get_vec_float (cpu, vm, i));
6414 }
6415
6416 static void
6417 do_vec_FMUL (sim_cpu *cpu)
6418 {
6419   /* instr [31]    = 0
6420      instr [30]    = half(0)/full(1)
6421      instr [29,23] = 10 1110 0
6422      instr [22]    = float(0)/double(1)
6423      instr [21]    = 1
6424      instr [20,16] = Vm
6425      instr [15,10] = 1101 11
6426      instr [9, 5]  = Vn
6427      instr [4, 0]  = Vd.  */
6428
6429   unsigned full = INSTR (30, 30);
6430   unsigned vm = INSTR (20, 16);
6431   unsigned vn = INSTR (9, 5);
6432   unsigned vd = INSTR (4, 0);
6433   unsigned i;
6434
6435   NYI_assert (29, 23, 0x5C);
6436   NYI_assert (21, 21, 1);
6437   NYI_assert (15, 10, 0x37);
6438
6439   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6440   if (INSTR (22, 22))
6441     {
6442       if (! full)
6443         HALT_UNALLOC;
6444
6445       for (i = 0; i < 2; i++)
6446         aarch64_set_vec_double (cpu, vd, i,
6447                                 aarch64_get_vec_double (cpu, vn, i)
6448                                 * aarch64_get_vec_double (cpu, vm, i));
6449     }
6450   else
6451     for (i = 0; i < (full ? 4 : 2); i++)
6452       aarch64_set_vec_float (cpu, vd, i,
6453                              aarch64_get_vec_float (cpu, vn, i)
6454                              * aarch64_get_vec_float (cpu, vm, i));
6455 }
6456
6457 static void
6458 do_vec_FADDP (sim_cpu *cpu)
6459 {
6460   /* instr [31]    = 0
6461      instr [30]    = half(0)/full(1)
6462      instr [29,23] = 10 1110 0
6463      instr [22]    = float(0)/double(1)
6464      instr [21]    = 1
6465      instr [20,16] = Vm
6466      instr [15,10] = 1101 01
6467      instr [9, 5]  = Vn
6468      instr [4, 0]  = Vd.  */
6469
6470   unsigned full = INSTR (30, 30);
6471   unsigned vm = INSTR (20, 16);
6472   unsigned vn = INSTR (9, 5);
6473   unsigned vd = INSTR (4, 0);
6474
6475   NYI_assert (29, 23, 0x5C);
6476   NYI_assert (21, 21, 1);
6477   NYI_assert (15, 10, 0x35);
6478
6479   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6480   if (INSTR (22, 22))
6481     {
6482       /* Extract values before adding them incase vd == vn/vm.  */
6483       double tmp1 = aarch64_get_vec_double (cpu, vn, 0);
6484       double tmp2 = aarch64_get_vec_double (cpu, vn, 1);
6485       double tmp3 = aarch64_get_vec_double (cpu, vm, 0);
6486       double tmp4 = aarch64_get_vec_double (cpu, vm, 1);
6487
6488       if (! full)
6489         HALT_UNALLOC;
6490
6491       aarch64_set_vec_double (cpu, vd, 0, tmp1 + tmp2);
6492       aarch64_set_vec_double (cpu, vd, 1, tmp3 + tmp4);
6493     }
6494   else
6495     {
6496       /* Extract values before adding them incase vd == vn/vm.  */
6497       float tmp1 = aarch64_get_vec_float (cpu, vn, 0);
6498       float tmp2 = aarch64_get_vec_float (cpu, vn, 1);
6499       float tmp5 = aarch64_get_vec_float (cpu, vm, 0);
6500       float tmp6 = aarch64_get_vec_float (cpu, vm, 1);
6501
6502       if (full)
6503         {
6504           float tmp3 = aarch64_get_vec_float (cpu, vn, 2);
6505           float tmp4 = aarch64_get_vec_float (cpu, vn, 3);
6506           float tmp7 = aarch64_get_vec_float (cpu, vm, 2);
6507           float tmp8 = aarch64_get_vec_float (cpu, vm, 3);
6508
6509           aarch64_set_vec_float (cpu, vd, 0, tmp1 + tmp2);
6510           aarch64_set_vec_float (cpu, vd, 1, tmp3 + tmp4);
6511           aarch64_set_vec_float (cpu, vd, 2, tmp5 + tmp6);
6512           aarch64_set_vec_float (cpu, vd, 3, tmp7 + tmp8);
6513         }
6514       else
6515         {
6516           aarch64_set_vec_float (cpu, vd, 0, tmp1 + tmp2);
6517           aarch64_set_vec_float (cpu, vd, 1, tmp5 + tmp6);
6518         }
6519     }
6520 }
6521
6522 static void
6523 do_vec_FSQRT (sim_cpu *cpu)
6524 {
6525   /* instr[31]    = 0
6526      instr[30]    = half(0)/full(1)
6527      instr[29,23] = 10 1110 1
6528      instr[22]    = single(0)/double(1)
6529      instr[21,10] = 10 0001 1111 10
6530      instr[9,5]   = Vsrc
6531      instr[4,0]   = Vdest.  */
6532
6533   unsigned vn = INSTR (9, 5);
6534   unsigned vd = INSTR (4, 0);
6535   unsigned full = INSTR (30, 30);
6536   int i;
6537
6538   NYI_assert (29, 23, 0x5D);
6539   NYI_assert (21, 10, 0x87E);
6540
6541   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6542   if (INSTR (22, 22))
6543     {
6544       if (! full)
6545         HALT_UNALLOC;
6546
6547       for (i = 0; i < 2; i++)
6548         aarch64_set_vec_double (cpu, vd, i,
6549                                 sqrt (aarch64_get_vec_double (cpu, vn, i)));
6550     }
6551   else
6552     {
6553       for (i = 0; i < (full ? 4 : 2); i++)
6554         aarch64_set_vec_float (cpu, vd, i,
6555                                sqrtf (aarch64_get_vec_float (cpu, vn, i)));
6556     }
6557 }
6558
6559 static void
6560 do_vec_FNEG (sim_cpu *cpu)
6561 {
6562   /* instr[31]    = 0
6563      instr[30]    = half (0)/full (1)
6564      instr[29,23] = 10 1110 1
6565      instr[22]    = single (0)/double (1)
6566      instr[21,10] = 10 0000 1111 10
6567      instr[9,5]   = Vsrc
6568      instr[4,0]   = Vdest.  */
6569
6570   unsigned vn = INSTR (9, 5);
6571   unsigned vd = INSTR (4, 0);
6572   unsigned full = INSTR (30, 30);
6573   int i;
6574
6575   NYI_assert (29, 23, 0x5D);
6576   NYI_assert (21, 10, 0x83E);
6577
6578   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6579   if (INSTR (22, 22))
6580     {
6581       if (! full)
6582         HALT_UNALLOC;
6583
6584       for (i = 0; i < 2; i++)
6585         aarch64_set_vec_double (cpu, vd, i,
6586                                 - aarch64_get_vec_double (cpu, vn, i));
6587     }
6588   else
6589     {
6590       for (i = 0; i < (full ? 4 : 2); i++)
6591         aarch64_set_vec_float (cpu, vd, i,
6592                                - aarch64_get_vec_float (cpu, vn, i));
6593     }
6594 }
6595
6596 static void
6597 do_vec_NOT (sim_cpu *cpu)
6598 {
6599   /* instr[31]    = 0
6600      instr[30]    = half (0)/full (1)
6601      instr[29,10] = 10 1110 0010 0000 0101 10
6602      instr[9,5]   = Vn
6603      instr[4.0]   = Vd.  */
6604
6605   unsigned vn = INSTR (9, 5);
6606   unsigned vd = INSTR (4, 0);
6607   unsigned i;
6608   int      full = INSTR (30, 30);
6609
6610   NYI_assert (29, 10, 0xB8816);
6611
6612   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6613   for (i = 0; i < (full ? 16 : 8); i++)
6614     aarch64_set_vec_u8 (cpu, vd, i, ~ aarch64_get_vec_u8 (cpu, vn, i));
6615 }
6616
6617 static unsigned int
6618 clz (uint64_t val, unsigned size)
6619 {
6620   uint64_t mask = 1;
6621   int      count;
6622
6623   mask <<= (size - 1);
6624   count = 0;
6625   do
6626     {
6627       if (val & mask)
6628         break;
6629       mask >>= 1;
6630       count ++;
6631     }
6632   while (mask);
6633
6634   return count;
6635 }
6636
6637 static void
6638 do_vec_CLZ (sim_cpu *cpu)
6639 {
6640   /* instr[31]    = 0
6641      instr[30]    = half (0)/full (1)
6642      instr[29,24] = 10 1110
6643      instr[23,22] = size
6644      instr[21,10] = 10 0000 0100 10
6645      instr[9,5]   = Vn
6646      instr[4.0]   = Vd.  */
6647
6648   unsigned vn = INSTR (9, 5);
6649   unsigned vd = INSTR (4, 0);
6650   unsigned i;
6651   int      full = INSTR (30,30);
6652
6653   NYI_assert (29, 24, 0x2E);
6654   NYI_assert (21, 10, 0x812);
6655
6656   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6657   switch (INSTR (23, 22))
6658     {
6659     case 0:
6660       for (i = 0; i < (full ? 16 : 8); i++)
6661         aarch64_set_vec_u8 (cpu, vd, i, clz (aarch64_get_vec_u8 (cpu, vn, i), 8));
6662       break;
6663     case 1:
6664       for (i = 0; i < (full ? 8 : 4); i++)
6665         aarch64_set_vec_u16 (cpu, vd, i, clz (aarch64_get_vec_u16 (cpu, vn, i), 16));
6666       break;
6667     case 2:
6668       for (i = 0; i < (full ? 4 : 2); i++)
6669         aarch64_set_vec_u32 (cpu, vd, i, clz (aarch64_get_vec_u32 (cpu, vn, i), 32));
6670       break;
6671     case 3:
6672       if (! full)
6673         HALT_UNALLOC;
6674       aarch64_set_vec_u64 (cpu, vd, 0, clz (aarch64_get_vec_u64 (cpu, vn, 0), 64));
6675       aarch64_set_vec_u64 (cpu, vd, 1, clz (aarch64_get_vec_u64 (cpu, vn, 1), 64));
6676       break;
6677     }
6678 }
6679
6680 static void
6681 do_vec_MOV_element (sim_cpu *cpu)
6682 {
6683   /* instr[31,21] = 0110 1110 000
6684      instr[20,16] = size & dest index
6685      instr[15]    = 0
6686      instr[14,11] = source index
6687      instr[10]    = 1
6688      instr[9,5]   = Vs
6689      instr[4.0]   = Vd.  */
6690
6691   unsigned vs = INSTR (9, 5);
6692   unsigned vd = INSTR (4, 0);
6693   unsigned src_index;
6694   unsigned dst_index;
6695
6696   NYI_assert (31, 21, 0x370);
6697   NYI_assert (15, 15, 0);
6698   NYI_assert (10, 10, 1);
6699
6700   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6701   if (INSTR (16, 16))
6702     {
6703       /* Move a byte.  */
6704       src_index = INSTR (14, 11);
6705       dst_index = INSTR (20, 17);
6706       aarch64_set_vec_u8 (cpu, vd, dst_index,
6707                           aarch64_get_vec_u8 (cpu, vs, src_index));
6708     }
6709   else if (INSTR (17, 17))
6710     {
6711       /* Move 16-bits.  */
6712       NYI_assert (11, 11, 0);
6713       src_index = INSTR (14, 12);
6714       dst_index = INSTR (20, 18);
6715       aarch64_set_vec_u16 (cpu, vd, dst_index,
6716                            aarch64_get_vec_u16 (cpu, vs, src_index));
6717     }
6718   else if (INSTR (18, 18))
6719     {
6720       /* Move 32-bits.  */
6721       NYI_assert (12, 11, 0);
6722       src_index = INSTR (14, 13);
6723       dst_index = INSTR (20, 19);
6724       aarch64_set_vec_u32 (cpu, vd, dst_index,
6725                            aarch64_get_vec_u32 (cpu, vs, src_index));
6726     }
6727   else
6728     {
6729       NYI_assert (19, 19, 1);
6730       NYI_assert (13, 11, 0);
6731       src_index = INSTR (14, 14);
6732       dst_index = INSTR (20, 20);
6733       aarch64_set_vec_u64 (cpu, vd, dst_index,
6734                            aarch64_get_vec_u64 (cpu, vs, src_index));
6735     }
6736 }
6737
6738 static void
6739 do_vec_REV32 (sim_cpu *cpu)
6740 {
6741   /* instr[31]    = 0
6742      instr[30]    = full/half
6743      instr[29,24] = 10 1110 
6744      instr[23,22] = size
6745      instr[21,10] = 10 0000 0000 10
6746      instr[9,5]   = Rn
6747      instr[4,0]   = Rd.  */
6748
6749   unsigned rn = INSTR (9, 5);
6750   unsigned rd = INSTR (4, 0);
6751   unsigned size = INSTR (23, 22);
6752   unsigned full = INSTR (30, 30);
6753   unsigned i;
6754   FRegister val;
6755
6756   NYI_assert (29, 24, 0x2E);
6757   NYI_assert (21, 10, 0x802);
6758
6759   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6760   switch (size)
6761     {
6762     case 0:
6763       for (i = 0; i < (full ? 16 : 8); i++)
6764         val.b[i ^ 0x3] = aarch64_get_vec_u8 (cpu, rn, i);
6765       break;
6766
6767     case 1:
6768       for (i = 0; i < (full ? 8 : 4); i++)
6769         val.h[i ^ 0x1] = aarch64_get_vec_u16 (cpu, rn, i);
6770       break;
6771
6772     default:
6773       HALT_UNALLOC;
6774     }
6775
6776   aarch64_set_vec_u64 (cpu, rd, 0, val.v[0]);
6777   if (full)
6778     aarch64_set_vec_u64 (cpu, rd, 1, val.v[1]);
6779 }
6780
6781 static void
6782 do_vec_EXT (sim_cpu *cpu)
6783 {
6784   /* instr[31]    = 0
6785      instr[30]    = full/half
6786      instr[29,21] = 10 1110 000
6787      instr[20,16] = Vm
6788      instr[15]    = 0
6789      instr[14,11] = source index
6790      instr[10]    = 0
6791      instr[9,5]   = Vn
6792      instr[4.0]   = Vd.  */
6793
6794   unsigned vm = INSTR (20, 16);
6795   unsigned vn = INSTR (9, 5);
6796   unsigned vd = INSTR (4, 0);
6797   unsigned src_index = INSTR (14, 11);
6798   unsigned full = INSTR (30, 30);
6799   unsigned i;
6800   unsigned j;
6801   FRegister val;
6802
6803   NYI_assert (31, 21, 0x370);
6804   NYI_assert (15, 15, 0);
6805   NYI_assert (10, 10, 0);
6806
6807   if (!full && (src_index & 0x8))
6808     HALT_UNALLOC;
6809
6810   j = 0;
6811
6812   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6813   for (i = src_index; i < (full ? 16 : 8); i++)
6814     val.b[j ++] = aarch64_get_vec_u8 (cpu, vn, i);
6815   for (i = 0; i < src_index; i++)
6816     val.b[j ++] = aarch64_get_vec_u8 (cpu, vm, i);
6817
6818   aarch64_set_vec_u64 (cpu, vd, 0, val.v[0]);
6819   if (full)
6820     aarch64_set_vec_u64 (cpu, vd, 1, val.v[1]);
6821 }
6822
6823 static void
6824 dexAdvSIMD0 (sim_cpu *cpu)
6825 {
6826   /* instr [28,25] = 0 111.  */
6827   if (    INSTR (15, 10) == 0x07
6828       && (INSTR (9, 5) ==
6829           INSTR (20, 16)))
6830     {
6831       if (INSTR (31, 21) == 0x075
6832           || INSTR (31, 21) == 0x275)
6833         {
6834           do_vec_MOV_whole_vector (cpu);
6835           return;
6836         }
6837     }
6838
6839   if (INSTR (29, 19) == 0x1E0)
6840     {
6841       do_vec_MOV_immediate (cpu);
6842       return;
6843     }
6844
6845   if (INSTR (29, 19) == 0x5E0)
6846     {
6847       do_vec_MVNI (cpu);
6848       return;
6849     }
6850
6851   if (INSTR (29, 19) == 0x1C0
6852       || INSTR (29, 19) == 0x1C1)
6853     {
6854       if (INSTR (15, 10) == 0x03)
6855         {
6856           do_vec_DUP_scalar_into_vector (cpu);
6857           return;
6858         }
6859     }
6860
6861   switch (INSTR (29, 24))
6862     {
6863     case 0x0E: do_vec_op1 (cpu); return;
6864     case 0x0F: do_vec_op2 (cpu); return;
6865
6866     case 0x2E:
6867       if (INSTR (21, 21) == 1)
6868         {
6869           switch (INSTR (15, 10))
6870             {
6871             case 0x02:
6872               do_vec_REV32 (cpu);
6873               return;
6874
6875             case 0x07:
6876               switch (INSTR (23, 22))
6877                 {
6878                 case 0: do_vec_EOR (cpu); return;
6879                 case 1: do_vec_BSL (cpu); return;
6880                 case 2:
6881                 case 3: do_vec_bit (cpu); return;
6882                 }
6883               break;
6884
6885             case 0x08: do_vec_sub_long (cpu); return;
6886             case 0x11: do_vec_USHL (cpu); return;
6887             case 0x12: do_vec_CLZ (cpu); return;
6888             case 0x16: do_vec_NOT (cpu); return;
6889             case 0x19: do_vec_max (cpu); return;
6890             case 0x1B: do_vec_min (cpu); return;
6891             case 0x21: do_vec_SUB (cpu); return;
6892             case 0x25: do_vec_MLS (cpu); return;
6893             case 0x31: do_vec_FminmaxNMP (cpu); return;
6894             case 0x35: do_vec_FADDP (cpu); return;
6895             case 0x37: do_vec_FMUL (cpu); return;
6896             case 0x3F: do_vec_FDIV (cpu); return;
6897
6898             case 0x3E:
6899               switch (INSTR (20, 16))
6900                 {
6901                 case 0x00: do_vec_FNEG (cpu); return;
6902                 case 0x01: do_vec_FSQRT (cpu); return;
6903                 default:   HALT_NYI;
6904                 }
6905
6906             case 0x0D:
6907             case 0x0F:
6908             case 0x22:
6909             case 0x23:
6910             case 0x26:
6911             case 0x2A:
6912             case 0x32:
6913             case 0x36:
6914             case 0x39:
6915             case 0x3A:
6916               do_vec_compare (cpu); return;
6917
6918             default:
6919               break;
6920             }
6921         }
6922
6923       if (INSTR (31, 21) == 0x370)
6924         {
6925           if (INSTR (10, 10))
6926             do_vec_MOV_element (cpu);
6927           else
6928             do_vec_EXT (cpu);
6929           return;
6930         }
6931
6932       switch (INSTR (21, 10))
6933         {
6934         case 0x82E: do_vec_neg (cpu); return;
6935         case 0x87E: do_vec_sqrt (cpu); return;
6936         default:
6937           if (INSTR (15, 10) == 0x30)
6938             {
6939               do_vec_mull (cpu);
6940               return;
6941             }
6942           break;
6943         }
6944       break;
6945
6946     case 0x2f:
6947       switch (INSTR (15, 10))
6948         {
6949         case 0x01: do_vec_SSHR_USHR (cpu); return;
6950         case 0x10:
6951         case 0x12: do_vec_mls_indexed (cpu); return;
6952         case 0x29: do_vec_xtl (cpu); return;
6953         default:
6954           HALT_NYI;
6955         }
6956
6957     default:
6958       break;
6959     }
6960
6961   HALT_NYI;
6962 }
6963
6964 /* 3 sources.  */
6965
6966 /* Float multiply add.  */
6967 static void
6968 fmadds (sim_cpu *cpu)
6969 {
6970   unsigned sa = INSTR (14, 10);
6971   unsigned sm = INSTR (20, 16);
6972   unsigned sn = INSTR ( 9,  5);
6973   unsigned sd = INSTR ( 4,  0);
6974
6975   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6976   aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sa)
6977                         + aarch64_get_FP_float (cpu, sn)
6978                         * aarch64_get_FP_float (cpu, sm));
6979 }
6980
6981 /* Double multiply add.  */
6982 static void
6983 fmaddd (sim_cpu *cpu)
6984 {
6985   unsigned sa = INSTR (14, 10);
6986   unsigned sm = INSTR (20, 16);
6987   unsigned sn = INSTR ( 9,  5);
6988   unsigned sd = INSTR ( 4,  0);
6989
6990   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
6991   aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sa)
6992                          + aarch64_get_FP_double (cpu, sn)
6993                          * aarch64_get_FP_double (cpu, sm));
6994 }
6995
6996 /* Float multiply subtract.  */
6997 static void
6998 fmsubs (sim_cpu *cpu)
6999 {
7000   unsigned sa = INSTR (14, 10);
7001   unsigned sm = INSTR (20, 16);
7002   unsigned sn = INSTR ( 9,  5);
7003   unsigned sd = INSTR ( 4,  0);
7004
7005   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7006   aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sa)
7007                         - aarch64_get_FP_float (cpu, sn)
7008                         * aarch64_get_FP_float (cpu, sm));
7009 }
7010
7011 /* Double multiply subtract.  */
7012 static void
7013 fmsubd (sim_cpu *cpu)
7014 {
7015   unsigned sa = INSTR (14, 10);
7016   unsigned sm = INSTR (20, 16);
7017   unsigned sn = INSTR ( 9,  5);
7018   unsigned sd = INSTR ( 4,  0);
7019
7020   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7021   aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sa)
7022                          - aarch64_get_FP_double (cpu, sn)
7023                          * aarch64_get_FP_double (cpu, sm));
7024 }
7025
7026 /* Float negative multiply add.  */
7027 static void
7028 fnmadds (sim_cpu *cpu)
7029 {
7030   unsigned sa = INSTR (14, 10);
7031   unsigned sm = INSTR (20, 16);
7032   unsigned sn = INSTR ( 9,  5);
7033   unsigned sd = INSTR ( 4,  0);
7034
7035   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7036   aarch64_set_FP_float (cpu, sd, - aarch64_get_FP_float (cpu, sa)
7037                         + (- aarch64_get_FP_float (cpu, sn))
7038                         * aarch64_get_FP_float (cpu, sm));
7039 }
7040
7041 /* Double negative multiply add.  */
7042 static void
7043 fnmaddd (sim_cpu *cpu)
7044 {
7045   unsigned sa = INSTR (14, 10);
7046   unsigned sm = INSTR (20, 16);
7047   unsigned sn = INSTR ( 9,  5);
7048   unsigned sd = INSTR ( 4,  0);
7049
7050   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7051   aarch64_set_FP_double (cpu, sd, - aarch64_get_FP_double (cpu, sa)
7052                          + (- aarch64_get_FP_double (cpu, sn))
7053                          * aarch64_get_FP_double (cpu, sm));
7054 }
7055
7056 /* Float negative multiply subtract.  */
7057 static void
7058 fnmsubs (sim_cpu *cpu)
7059 {
7060   unsigned sa = INSTR (14, 10);
7061   unsigned sm = INSTR (20, 16);
7062   unsigned sn = INSTR ( 9,  5);
7063   unsigned sd = INSTR ( 4,  0);
7064
7065   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7066   aarch64_set_FP_float (cpu, sd, - aarch64_get_FP_float (cpu, sa)
7067                         + aarch64_get_FP_float (cpu, sn)
7068                         * aarch64_get_FP_float (cpu, sm));
7069 }
7070
7071 /* Double negative multiply subtract.  */
7072 static void
7073 fnmsubd (sim_cpu *cpu)
7074 {
7075   unsigned sa = INSTR (14, 10);
7076   unsigned sm = INSTR (20, 16);
7077   unsigned sn = INSTR ( 9,  5);
7078   unsigned sd = INSTR ( 4,  0);
7079
7080   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7081   aarch64_set_FP_double (cpu, sd, - aarch64_get_FP_double (cpu, sa)
7082                          + aarch64_get_FP_double (cpu, sn)
7083                          * aarch64_get_FP_double (cpu, sm));
7084 }
7085
7086 static void
7087 dexSimpleFPDataProc3Source (sim_cpu *cpu)
7088 {
7089   /* instr[31]    ==> M : 0 ==> OK, 1 ==> UNALLOC
7090      instr[30]    = 0
7091      instr[29]    ==> S :  0 ==> OK, 1 ==> UNALLOC
7092      instr[28,25] = 1111
7093      instr[24]    = 1
7094      instr[23,22] ==> type : 0 ==> single, 01 ==> double, 1x ==> UNALLOC
7095      instr[21]    ==> o1 : 0 ==> unnegated, 1 ==> negated
7096      instr[15]    ==> o2 : 0 ==> ADD, 1 ==> SUB  */
7097
7098   uint32_t M_S = (INSTR (31, 31) << 1) | INSTR (29, 29);
7099   /* dispatch on combined type:o1:o2.  */
7100   uint32_t dispatch = (INSTR (23, 21) << 1) | INSTR (15, 15);
7101
7102   if (M_S != 0)
7103     HALT_UNALLOC;
7104
7105   switch (dispatch)
7106     {
7107     case 0: fmadds (cpu); return;
7108     case 1: fmsubs (cpu); return;
7109     case 2: fnmadds (cpu); return;
7110     case 3: fnmsubs (cpu); return;
7111     case 4: fmaddd (cpu); return;
7112     case 5: fmsubd (cpu); return;
7113     case 6: fnmaddd (cpu); return;
7114     case 7: fnmsubd (cpu); return;
7115     default:
7116       /* type > 1 is currently unallocated.  */
7117       HALT_UNALLOC;
7118     }
7119 }
7120
7121 static void
7122 dexSimpleFPFixedConvert (sim_cpu *cpu)
7123 {
7124   HALT_NYI;
7125 }
7126
7127 static void
7128 dexSimpleFPCondCompare (sim_cpu *cpu)
7129 {
7130   /* instr [31,23] = 0001 1110 0
7131      instr [22]    = type
7132      instr [21]    = 1
7133      instr [20,16] = Rm
7134      instr [15,12] = condition
7135      instr [11,10] = 01
7136      instr [9,5]   = Rn
7137      instr [4]     = 0
7138      instr [3,0]   = nzcv  */
7139
7140   unsigned rm = INSTR (20, 16);
7141   unsigned rn = INSTR (9, 5);
7142
7143   NYI_assert (31, 23, 0x3C);
7144   NYI_assert (11, 10, 0x1);
7145   NYI_assert (4,  4,  0);
7146
7147   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7148   if (! testConditionCode (cpu, INSTR (15, 12)))
7149     {
7150       aarch64_set_CPSR (cpu, INSTR (3, 0));
7151       return;
7152     }
7153
7154   if (INSTR (22, 22))
7155     {
7156       /* Double precision.  */
7157       double val1 = aarch64_get_vec_double (cpu, rn, 0);
7158       double val2 = aarch64_get_vec_double (cpu, rm, 0);
7159
7160       /* FIXME: Check for NaNs.  */
7161       if (val1 == val2)
7162         aarch64_set_CPSR (cpu, (Z | C));
7163       else if (val1 < val2)
7164         aarch64_set_CPSR (cpu, N);
7165       else /* val1 > val2 */
7166         aarch64_set_CPSR (cpu, C);
7167     }
7168   else
7169     {
7170       /* Single precision.  */
7171       float val1 = aarch64_get_vec_float (cpu, rn, 0);
7172       float val2 = aarch64_get_vec_float (cpu, rm, 0);
7173
7174       /* FIXME: Check for NaNs.  */
7175       if (val1 == val2)
7176         aarch64_set_CPSR (cpu, (Z | C));
7177       else if (val1 < val2)
7178         aarch64_set_CPSR (cpu, N);
7179       else /* val1 > val2 */
7180         aarch64_set_CPSR (cpu, C);
7181     }
7182 }
7183
7184 /* 2 sources.  */
7185
7186 /* Float add.  */
7187 static void
7188 fadds (sim_cpu *cpu)
7189 {
7190   unsigned sm = INSTR (20, 16);
7191   unsigned sn = INSTR ( 9,  5);
7192   unsigned sd = INSTR ( 4,  0);
7193
7194   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7195   aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn)
7196                         + aarch64_get_FP_float (cpu, sm));
7197 }
7198
7199 /* Double add.  */
7200 static void
7201 faddd (sim_cpu *cpu)
7202 {
7203   unsigned sm = INSTR (20, 16);
7204   unsigned sn = INSTR ( 9,  5);
7205   unsigned sd = INSTR ( 4,  0);
7206
7207   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7208   aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn)
7209                          + aarch64_get_FP_double (cpu, sm));
7210 }
7211
7212 /* Float divide.  */
7213 static void
7214 fdivs (sim_cpu *cpu)
7215 {
7216   unsigned sm = INSTR (20, 16);
7217   unsigned sn = INSTR ( 9,  5);
7218   unsigned sd = INSTR ( 4,  0);
7219
7220   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7221   aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn)
7222                         / aarch64_get_FP_float (cpu, sm));
7223 }
7224
7225 /* Double divide.  */
7226 static void
7227 fdivd (sim_cpu *cpu)
7228 {
7229   unsigned sm = INSTR (20, 16);
7230   unsigned sn = INSTR ( 9,  5);
7231   unsigned sd = INSTR ( 4,  0);
7232
7233   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7234   aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn)
7235                          / aarch64_get_FP_double (cpu, sm));
7236 }
7237
7238 /* Float multiply.  */
7239 static void
7240 fmuls (sim_cpu *cpu)
7241 {
7242   unsigned sm = INSTR (20, 16);
7243   unsigned sn = INSTR ( 9,  5);
7244   unsigned sd = INSTR ( 4,  0);
7245
7246   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7247   aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn)
7248                         * aarch64_get_FP_float (cpu, sm));
7249 }
7250
7251 /* Double multiply.  */
7252 static void
7253 fmuld (sim_cpu *cpu)
7254 {
7255   unsigned sm = INSTR (20, 16);
7256   unsigned sn = INSTR ( 9,  5);
7257   unsigned sd = INSTR ( 4,  0);
7258
7259   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7260   aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn)
7261                          * aarch64_get_FP_double (cpu, sm));
7262 }
7263
7264 /* Float negate and multiply.  */
7265 static void
7266 fnmuls (sim_cpu *cpu)
7267 {
7268   unsigned sm = INSTR (20, 16);
7269   unsigned sn = INSTR ( 9,  5);
7270   unsigned sd = INSTR ( 4,  0);
7271
7272   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7273   aarch64_set_FP_float (cpu, sd, - (aarch64_get_FP_float (cpu, sn)
7274                                     * aarch64_get_FP_float (cpu, sm)));
7275 }
7276
7277 /* Double negate and multiply.  */
7278 static void
7279 fnmuld (sim_cpu *cpu)
7280 {
7281   unsigned sm = INSTR (20, 16);
7282   unsigned sn = INSTR ( 9,  5);
7283   unsigned sd = INSTR ( 4,  0);
7284
7285   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7286   aarch64_set_FP_double (cpu, sd, - (aarch64_get_FP_double (cpu, sn)
7287                                      * aarch64_get_FP_double (cpu, sm)));
7288 }
7289
7290 /* Float subtract.  */
7291 static void
7292 fsubs (sim_cpu *cpu)
7293 {
7294   unsigned sm = INSTR (20, 16);
7295   unsigned sn = INSTR ( 9,  5);
7296   unsigned sd = INSTR ( 4,  0);
7297
7298   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7299   aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn)
7300                         - aarch64_get_FP_float (cpu, sm));
7301 }
7302
7303 /* Double subtract.  */
7304 static void
7305 fsubd (sim_cpu *cpu)
7306 {
7307   unsigned sm = INSTR (20, 16);
7308   unsigned sn = INSTR ( 9,  5);
7309   unsigned sd = INSTR ( 4,  0);
7310
7311   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7312   aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn)
7313                          - aarch64_get_FP_double (cpu, sm));
7314 }
7315
7316 static void
7317 do_FMINNM (sim_cpu *cpu)
7318 {
7319   /* instr[31,23] = 0 0011 1100
7320      instr[22]    = float(0)/double(1)
7321      instr[21]    = 1
7322      instr[20,16] = Sm
7323      instr[15,10] = 01 1110
7324      instr[9,5]   = Sn
7325      instr[4,0]   = Cpu  */
7326
7327   unsigned sm = INSTR (20, 16);
7328   unsigned sn = INSTR ( 9,  5);
7329   unsigned sd = INSTR ( 4,  0);
7330
7331   NYI_assert (31, 23, 0x03C);
7332   NYI_assert (15, 10, 0x1E);
7333
7334   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7335   if (INSTR (22, 22))
7336     aarch64_set_FP_double (cpu, sd,
7337                            dminnm (aarch64_get_FP_double (cpu, sn),
7338                                    aarch64_get_FP_double (cpu, sm)));
7339   else
7340     aarch64_set_FP_float (cpu, sd,
7341                           fminnm (aarch64_get_FP_float (cpu, sn),
7342                                   aarch64_get_FP_float (cpu, sm)));
7343 }
7344
7345 static void
7346 do_FMAXNM (sim_cpu *cpu)
7347 {
7348   /* instr[31,23] = 0 0011 1100
7349      instr[22]    = float(0)/double(1)
7350      instr[21]    = 1
7351      instr[20,16] = Sm
7352      instr[15,10] = 01 1010
7353      instr[9,5]   = Sn
7354      instr[4,0]   = Cpu  */
7355
7356   unsigned sm = INSTR (20, 16);
7357   unsigned sn = INSTR ( 9,  5);
7358   unsigned sd = INSTR ( 4,  0);
7359
7360   NYI_assert (31, 23, 0x03C);
7361   NYI_assert (15, 10, 0x1A);
7362
7363   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7364   if (INSTR (22, 22))
7365     aarch64_set_FP_double (cpu, sd,
7366                            dmaxnm (aarch64_get_FP_double (cpu, sn),
7367                                    aarch64_get_FP_double (cpu, sm)));
7368   else
7369     aarch64_set_FP_float (cpu, sd,
7370                           fmaxnm (aarch64_get_FP_float (cpu, sn),
7371                                   aarch64_get_FP_float (cpu, sm)));
7372 }
7373
7374 static void
7375 dexSimpleFPDataProc2Source (sim_cpu *cpu)
7376 {
7377   /* instr[31]    ==> M : 0 ==> OK, 1 ==> UNALLOC
7378      instr[30]    = 0
7379      instr[29]    ==> S :  0 ==> OK, 1 ==> UNALLOC
7380      instr[28,25] = 1111
7381      instr[24]    = 0
7382      instr[23,22] ==> type : 0 ==> single, 01 ==> double, 1x ==> UNALLOC
7383      instr[21]    = 1
7384      instr[20,16] = Vm
7385      instr[15,12] ==> opcode : 0000 ==> FMUL, 0001 ==> FDIV
7386                                0010 ==> FADD, 0011 ==> FSUB,
7387                                0100 ==> FMAX, 0101 ==> FMIN
7388                                0110 ==> FMAXNM, 0111 ==> FMINNM
7389                                1000 ==> FNMUL, ow ==> UNALLOC
7390      instr[11,10] = 10
7391      instr[9,5]   = Vn
7392      instr[4,0]   = Vd  */
7393
7394   uint32_t M_S = (INSTR (31, 31) << 1) | INSTR (29, 29);
7395   uint32_t type = INSTR (23, 22);
7396   /* Dispatch on opcode.  */
7397   uint32_t dispatch = INSTR (15, 12);
7398
7399   if (type > 1)
7400     HALT_UNALLOC;
7401
7402   if (M_S != 0)
7403     HALT_UNALLOC;
7404
7405   if (type)
7406     switch (dispatch)
7407       {
7408       case 0: fmuld (cpu); return;
7409       case 1: fdivd (cpu); return;
7410       case 2: faddd (cpu); return;
7411       case 3: fsubd (cpu); return;
7412       case 6: do_FMAXNM (cpu); return;
7413       case 7: do_FMINNM (cpu); return;
7414       case 8: fnmuld (cpu); return;
7415
7416         /* Have not yet implemented fmax and fmin.  */
7417       case 4:
7418       case 5:
7419         HALT_NYI;
7420
7421       default:
7422         HALT_UNALLOC;
7423       }
7424   else /* type == 0 => floats.  */
7425     switch (dispatch)
7426       {
7427       case 0: fmuls (cpu); return;
7428       case 1: fdivs (cpu); return;
7429       case 2: fadds (cpu); return;
7430       case 3: fsubs (cpu); return;
7431       case 6: do_FMAXNM (cpu); return;
7432       case 7: do_FMINNM (cpu); return;
7433       case 8: fnmuls (cpu); return;
7434
7435       case 4:
7436       case 5:
7437         HALT_NYI;
7438
7439       default:
7440         HALT_UNALLOC;
7441       }
7442 }
7443
7444 static void
7445 dexSimpleFPCondSelect (sim_cpu *cpu)
7446 {
7447   /* FCSEL
7448      instr[31,23] = 0 0011 1100
7449      instr[22]    = 0=>single 1=>double
7450      instr[21]    = 1
7451      instr[20,16] = Sm
7452      instr[15,12] = cond
7453      instr[11,10] = 11
7454      instr[9,5]   = Sn
7455      instr[4,0]   = Cpu  */
7456   unsigned sm = INSTR (20, 16);
7457   unsigned sn = INSTR ( 9, 5);
7458   unsigned sd = INSTR ( 4, 0);
7459   uint32_t set = testConditionCode (cpu, INSTR (15, 12));
7460
7461   NYI_assert (31, 23, 0x03C);
7462   NYI_assert (11, 10, 0x3);
7463
7464   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7465   if (INSTR (22, 22))
7466     aarch64_set_FP_double (cpu, sd, set ? sn : sm);
7467   else
7468     aarch64_set_FP_float (cpu, sd, set ? sn : sm);
7469 }
7470
7471 /* Store 32 bit unscaled signed 9 bit.  */
7472 static void
7473 fsturs (sim_cpu *cpu, int32_t offset)
7474 {
7475   unsigned int rn = INSTR (9, 5);
7476   unsigned int st = INSTR (4, 0);
7477
7478   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7479   aarch64_set_mem_u32 (cpu, aarch64_get_reg_u64 (cpu, rn, 1) + offset,
7480                        aarch64_get_vec_u32 (cpu, st, 0));
7481 }
7482
7483 /* Store 64 bit unscaled signed 9 bit.  */
7484 static void
7485 fsturd (sim_cpu *cpu, int32_t offset)
7486 {
7487   unsigned int rn = INSTR (9, 5);
7488   unsigned int st = INSTR (4, 0);
7489
7490   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7491   aarch64_set_mem_u64 (cpu, aarch64_get_reg_u64 (cpu, rn, 1) + offset,
7492                        aarch64_get_vec_u64 (cpu, st, 0));
7493 }
7494
7495 /* Store 128 bit unscaled signed 9 bit.  */
7496 static void
7497 fsturq (sim_cpu *cpu, int32_t offset)
7498 {
7499   unsigned int rn = INSTR (9, 5);
7500   unsigned int st = INSTR (4, 0);
7501   FRegister a;
7502
7503   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7504   aarch64_get_FP_long_double (cpu, st, & a);
7505   aarch64_set_mem_long_double (cpu,
7506                                aarch64_get_reg_u64 (cpu, rn, 1)
7507                                + offset, a);
7508 }
7509
7510 /* TODO FP move register.  */
7511
7512 /* 32 bit fp to fp move register.  */
7513 static void
7514 ffmovs (sim_cpu *cpu)
7515 {
7516   unsigned int rn = INSTR (9, 5);
7517   unsigned int st = INSTR (4, 0);
7518
7519   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7520   aarch64_set_FP_float (cpu, st, aarch64_get_FP_float (cpu, rn));
7521 }
7522
7523 /* 64 bit fp to fp move register.  */
7524 static void
7525 ffmovd (sim_cpu *cpu)
7526 {
7527   unsigned int rn = INSTR (9, 5);
7528   unsigned int st = INSTR (4, 0);
7529
7530   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7531   aarch64_set_FP_double (cpu, st, aarch64_get_FP_double (cpu, rn));
7532 }
7533
7534 /* 32 bit GReg to Vec move register.  */
7535 static void
7536 fgmovs (sim_cpu *cpu)
7537 {
7538   unsigned int rn = INSTR (9, 5);
7539   unsigned int st = INSTR (4, 0);
7540
7541   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7542   aarch64_set_vec_u32 (cpu, st, 0, aarch64_get_reg_u32 (cpu, rn, NO_SP));
7543 }
7544
7545 /* 64 bit g to fp move register.  */
7546 static void
7547 fgmovd (sim_cpu *cpu)
7548 {
7549   unsigned int rn = INSTR (9, 5);
7550   unsigned int st = INSTR (4, 0);
7551
7552   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7553   aarch64_set_vec_u64 (cpu, st, 0, aarch64_get_reg_u64 (cpu, rn, NO_SP));
7554 }
7555
7556 /* 32 bit fp to g move register.  */
7557 static void
7558 gfmovs (sim_cpu *cpu)
7559 {
7560   unsigned int rn = INSTR (9, 5);
7561   unsigned int st = INSTR (4, 0);
7562
7563   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7564   aarch64_set_reg_u64 (cpu, st, NO_SP, aarch64_get_vec_u32 (cpu, rn, 0));
7565 }
7566
7567 /* 64 bit fp to g move register.  */
7568 static void
7569 gfmovd (sim_cpu *cpu)
7570 {
7571   unsigned int rn = INSTR (9, 5);
7572   unsigned int st = INSTR (4, 0);
7573
7574   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7575   aarch64_set_reg_u64 (cpu, st, NO_SP, aarch64_get_vec_u64 (cpu, rn, 0));
7576 }
7577
7578 /* FP move immediate
7579
7580    These install an immediate 8 bit value in the target register
7581    where the 8 bits comprise 1 sign bit, 4 bits of fraction and a 3
7582    bit exponent.  */
7583
7584 static void
7585 fmovs (sim_cpu *cpu)
7586 {
7587   unsigned int sd = INSTR (4, 0);
7588   uint32_t imm = INSTR (20, 13);
7589   float f = fp_immediate_for_encoding_32 (imm);
7590
7591   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7592   aarch64_set_FP_float (cpu, sd, f);
7593 }
7594
7595 static void
7596 fmovd (sim_cpu *cpu)
7597 {
7598   unsigned int sd = INSTR (4, 0);
7599   uint32_t imm = INSTR (20, 13);
7600   double d = fp_immediate_for_encoding_64 (imm);
7601
7602   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7603   aarch64_set_FP_double (cpu, sd, d);
7604 }
7605
7606 static void
7607 dexSimpleFPImmediate (sim_cpu *cpu)
7608 {
7609   /* instr[31,23] == 00111100
7610      instr[22]    == type : single(0)/double(1)
7611      instr[21]    == 1
7612      instr[20,13] == imm8
7613      instr[12,10] == 100
7614      instr[9,5]   == imm5 : 00000 ==> PK, ow ==> UNALLOC
7615      instr[4,0]   == Rd  */
7616   uint32_t imm5 = INSTR (9, 5);
7617
7618   NYI_assert (31, 23, 0x3C);
7619
7620   if (imm5 != 0)
7621     HALT_UNALLOC;
7622
7623   if (INSTR (22, 22))
7624     fmovd (cpu);
7625   else
7626     fmovs (cpu);
7627 }
7628
7629 /* TODO specific decode and execute for group Load Store.  */
7630
7631 /* TODO FP load/store single register (unscaled offset).  */
7632
7633 /* TODO load 8 bit unscaled signed 9 bit.  */
7634 /* TODO load 16 bit unscaled signed 9 bit.  */
7635
7636 /* Load 32 bit unscaled signed 9 bit.  */
7637 static void
7638 fldurs (sim_cpu *cpu, int32_t offset)
7639 {
7640   unsigned int rn = INSTR (9, 5);
7641   unsigned int st = INSTR (4, 0);
7642
7643   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7644   aarch64_set_vec_u32 (cpu, st, 0, aarch64_get_mem_u32
7645                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset));
7646 }
7647
7648 /* Load 64 bit unscaled signed 9 bit.  */
7649 static void
7650 fldurd (sim_cpu *cpu, int32_t offset)
7651 {
7652   unsigned int rn = INSTR (9, 5);
7653   unsigned int st = INSTR (4, 0);
7654
7655   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7656   aarch64_set_vec_u64 (cpu, st, 0, aarch64_get_mem_u64
7657                        (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset));
7658 }
7659
7660 /* Load 128 bit unscaled signed 9 bit.  */
7661 static void
7662 fldurq (sim_cpu *cpu, int32_t offset)
7663 {
7664   unsigned int rn = INSTR (9, 5);
7665   unsigned int st = INSTR (4, 0);
7666   FRegister a;
7667   uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset;
7668
7669   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7670   aarch64_get_mem_long_double (cpu, addr, & a);
7671   aarch64_set_FP_long_double (cpu, st, a);
7672 }
7673
7674 /* TODO store 8 bit unscaled signed 9 bit.  */
7675 /* TODO store 16 bit unscaled signed 9 bit.  */
7676
7677
7678 /* 1 source.  */
7679
7680 /* Float absolute value.  */
7681 static void
7682 fabss (sim_cpu *cpu)
7683 {
7684   unsigned sn = INSTR (9, 5);
7685   unsigned sd = INSTR (4, 0);
7686   float value = aarch64_get_FP_float (cpu, sn);
7687
7688   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7689   aarch64_set_FP_float (cpu, sd, fabsf (value));
7690 }
7691
7692 /* Double absolute value.  */
7693 static void
7694 fabcpu (sim_cpu *cpu)
7695 {
7696   unsigned sn = INSTR (9, 5);
7697   unsigned sd = INSTR (4, 0);
7698   double value = aarch64_get_FP_double (cpu, sn);
7699
7700   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7701   aarch64_set_FP_double (cpu, sd, fabs (value));
7702 }
7703
7704 /* Float negative value.  */
7705 static void
7706 fnegs (sim_cpu *cpu)
7707 {
7708   unsigned sn = INSTR (9, 5);
7709   unsigned sd = INSTR (4, 0);
7710
7711   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7712   aarch64_set_FP_float (cpu, sd, - aarch64_get_FP_float (cpu, sn));
7713 }
7714
7715 /* Double negative value.  */
7716 static void
7717 fnegd (sim_cpu *cpu)
7718 {
7719   unsigned sn = INSTR (9, 5);
7720   unsigned sd = INSTR (4, 0);
7721
7722   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7723   aarch64_set_FP_double (cpu, sd, - aarch64_get_FP_double (cpu, sn));
7724 }
7725
7726 /* Float square root.  */
7727 static void
7728 fsqrts (sim_cpu *cpu)
7729 {
7730   unsigned sn = INSTR (9, 5);
7731   unsigned sd = INSTR (4, 0);
7732
7733   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7734   aarch64_set_FP_float (cpu, sd, sqrtf (aarch64_get_FP_float (cpu, sn)));
7735 }
7736
7737 /* Double square root.  */
7738 static void
7739 fsqrtd (sim_cpu *cpu)
7740 {
7741   unsigned sn = INSTR (9, 5);
7742   unsigned sd = INSTR (4, 0);
7743
7744   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7745   aarch64_set_FP_double (cpu, sd,
7746                          sqrt (aarch64_get_FP_double (cpu, sn)));
7747 }
7748
7749 /* Convert double to float.  */
7750 static void
7751 fcvtds (sim_cpu *cpu)
7752 {
7753   unsigned sn = INSTR (9, 5);
7754   unsigned sd = INSTR (4, 0);
7755
7756   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7757   aarch64_set_FP_float (cpu, sd, (float) aarch64_get_FP_double (cpu, sn));
7758 }
7759
7760 /* Convert float to double.  */
7761 static void
7762 fcvtcpu (sim_cpu *cpu)
7763 {
7764   unsigned sn = INSTR (9, 5);
7765   unsigned sd = INSTR (4, 0);
7766
7767   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7768   aarch64_set_FP_double (cpu, sd, (double) aarch64_get_FP_float (cpu, sn));
7769 }
7770
7771 static void
7772 do_FRINT (sim_cpu *cpu)
7773 {
7774   /* instr[31,23] = 0001 1110 0
7775      instr[22]    = single(0)/double(1)
7776      instr[21,18] = 1001
7777      instr[17,15] = rounding mode
7778      instr[14,10] = 10000
7779      instr[9,5]   = source
7780      instr[4,0]   = dest  */
7781
7782   float val;
7783   unsigned rs = INSTR (9, 5);
7784   unsigned rd = INSTR (4, 0);
7785   unsigned int rmode = INSTR (17, 15);
7786
7787   NYI_assert (31, 23, 0x03C);
7788   NYI_assert (21, 18, 0x9);
7789   NYI_assert (14, 10, 0x10);
7790
7791   if (rmode == 6 || rmode == 7)
7792     /* FIXME: Add support for rmode == 6 exactness check.  */
7793     rmode = uimm (aarch64_get_FPSR (cpu), 23, 22);
7794
7795   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7796   if (INSTR (22, 22))
7797     {
7798       double val = aarch64_get_FP_double (cpu, rs);
7799
7800       switch (rmode)
7801         {
7802         case 0: /* mode N: nearest or even.  */
7803           {
7804             double rval = round (val);
7805
7806             if (val - rval == 0.5)
7807               {
7808                 if (((rval / 2.0) * 2.0) != rval)
7809                   rval += 1.0;
7810               }
7811
7812             aarch64_set_FP_double (cpu, rd, round (val));
7813             return;
7814           }
7815
7816         case 1: /* mode P: towards +inf.  */
7817           if (val < 0.0)
7818             aarch64_set_FP_double (cpu, rd, trunc (val));
7819           else
7820             aarch64_set_FP_double (cpu, rd, round (val));
7821           return;
7822
7823         case 2: /* mode M: towards -inf.  */
7824           if (val < 0.0)
7825             aarch64_set_FP_double (cpu, rd, round (val));
7826           else
7827             aarch64_set_FP_double (cpu, rd, trunc (val));
7828           return;
7829
7830         case 3: /* mode Z: towards 0.  */
7831           aarch64_set_FP_double (cpu, rd, trunc (val));
7832           return;
7833
7834         case 4: /* mode A: away from 0.  */
7835           aarch64_set_FP_double (cpu, rd, round (val));
7836           return;
7837
7838         case 6: /* mode X: use FPCR with exactness check.  */
7839         case 7: /* mode I: use FPCR mode.  */
7840           HALT_NYI;
7841
7842         default:
7843           HALT_UNALLOC;
7844         }
7845     }
7846
7847   val = aarch64_get_FP_float (cpu, rs);
7848
7849   switch (rmode)
7850     {
7851     case 0: /* mode N: nearest or even.  */
7852       {
7853         float rval = roundf (val);
7854
7855         if (val - rval == 0.5)
7856           {
7857             if (((rval / 2.0) * 2.0) != rval)
7858               rval += 1.0;
7859           }
7860
7861         aarch64_set_FP_float (cpu, rd, rval);
7862         return;
7863       }
7864
7865     case 1: /* mode P: towards +inf.  */
7866       if (val < 0.0)
7867         aarch64_set_FP_float (cpu, rd, truncf (val));
7868       else
7869         aarch64_set_FP_float (cpu, rd, roundf (val));
7870       return;
7871
7872     case 2: /* mode M: towards -inf.  */
7873       if (val < 0.0)
7874         aarch64_set_FP_float (cpu, rd, truncf (val));
7875       else
7876         aarch64_set_FP_float (cpu, rd, roundf (val));
7877       return;
7878
7879     case 3: /* mode Z: towards 0.  */
7880       aarch64_set_FP_float (cpu, rd, truncf (val));
7881       return;
7882
7883     case 4: /* mode A: away from 0.  */
7884       aarch64_set_FP_float (cpu, rd, roundf (val));
7885       return;
7886
7887     case 6: /* mode X: use FPCR with exactness check.  */
7888     case 7: /* mode I: use FPCR mode.  */
7889       HALT_NYI;
7890
7891     default:
7892       HALT_UNALLOC;
7893     }
7894 }
7895
7896 /* Convert half to float.  */
7897 static void
7898 do_FCVT_half_to_single (sim_cpu *cpu)
7899 {
7900   unsigned rn = INSTR (9, 5);
7901   unsigned rd = INSTR (4, 0);
7902
7903   NYI_assert (31, 10, 0x7B890);
7904
7905   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7906   aarch64_set_FP_float (cpu, rd, (float) aarch64_get_FP_half  (cpu, rn));
7907 }
7908
7909 /* Convert half to double.  */
7910 static void
7911 do_FCVT_half_to_double (sim_cpu *cpu)
7912 {
7913   unsigned rn = INSTR (9, 5);
7914   unsigned rd = INSTR (4, 0);
7915
7916   NYI_assert (31, 10, 0x7B8B0);
7917
7918   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7919   aarch64_set_FP_double (cpu, rd, (double) aarch64_get_FP_half  (cpu, rn));
7920 }
7921
7922 static void
7923 do_FCVT_single_to_half (sim_cpu *cpu)
7924 {
7925   unsigned rn = INSTR (9, 5);
7926   unsigned rd = INSTR (4, 0);
7927
7928   NYI_assert (31, 10, 0x788F0);
7929
7930   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7931   aarch64_set_FP_half (cpu, rd, aarch64_get_FP_float  (cpu, rn));
7932 }
7933
7934 /* Convert double to half.  */
7935 static void
7936 do_FCVT_double_to_half (sim_cpu *cpu)
7937 {
7938   unsigned rn = INSTR (9, 5);
7939   unsigned rd = INSTR (4, 0);
7940
7941   NYI_assert (31, 10, 0x798F0);
7942
7943   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
7944   aarch64_set_FP_half (cpu, rd, (float) aarch64_get_FP_double  (cpu, rn));
7945 }
7946
7947 static void
7948 dexSimpleFPDataProc1Source (sim_cpu *cpu)
7949 {
7950   /* instr[31]    ==> M : 0 ==> OK, 1 ==> UNALLOC
7951      instr[30]    = 0
7952      instr[29]    ==> S :  0 ==> OK, 1 ==> UNALLOC
7953      instr[28,25] = 1111
7954      instr[24]    = 0
7955      instr[23,22] ==> type : 00 ==> source is single,
7956                              01 ==> source is double
7957                              10 ==> UNALLOC
7958                              11 ==> UNALLOC or source is half
7959      instr[21]    = 1
7960      instr[20,15] ==> opcode : with type 00 or 01
7961                                000000 ==> FMOV, 000001 ==> FABS,
7962                                000010 ==> FNEG, 000011 ==> FSQRT,
7963                                000100 ==> UNALLOC, 000101 ==> FCVT,(to single/double)
7964                                000110 ==> UNALLOC, 000111 ==> FCVT (to half)
7965                                001000 ==> FRINTN, 001001 ==> FRINTP,
7966                                001010 ==> FRINTM, 001011 ==> FRINTZ,
7967                                001100 ==> FRINTA, 001101 ==> UNALLOC
7968                                001110 ==> FRINTX, 001111 ==> FRINTI
7969                                with type 11
7970                                000100 ==> FCVT (half-to-single)
7971                                000101 ==> FCVT (half-to-double)
7972                                instr[14,10] = 10000.  */
7973
7974   uint32_t M_S = (INSTR (31, 31) << 1) | INSTR (29, 29);
7975   uint32_t type   = INSTR (23, 22);
7976   uint32_t opcode = INSTR (20, 15);
7977
7978   if (M_S != 0)
7979     HALT_UNALLOC;
7980
7981   if (type == 3)
7982     {
7983       if (opcode == 4)
7984         do_FCVT_half_to_single (cpu);
7985       else if (opcode == 5)
7986         do_FCVT_half_to_double (cpu);
7987       else
7988         HALT_UNALLOC;
7989       return;
7990     }
7991
7992   if (type == 2)
7993     HALT_UNALLOC;
7994
7995   switch (opcode)
7996     {
7997     case 0:
7998       if (type)
7999         ffmovd (cpu);
8000       else
8001         ffmovs (cpu);
8002       return;
8003
8004     case 1:
8005       if (type)
8006         fabcpu (cpu);
8007       else
8008         fabss (cpu);
8009       return;
8010
8011     case 2:
8012       if (type)
8013         fnegd (cpu);
8014       else
8015         fnegs (cpu);
8016       return;
8017
8018     case 3:
8019       if (type)
8020         fsqrtd (cpu);
8021       else
8022         fsqrts (cpu);
8023       return;
8024
8025     case 4:
8026       if (type)
8027         fcvtds (cpu);
8028       else
8029         HALT_UNALLOC;
8030       return;
8031
8032     case 5:
8033       if (type)
8034         HALT_UNALLOC;
8035       fcvtcpu (cpu);
8036       return;
8037
8038     case 8:             /* FRINTN etc.  */
8039     case 9:
8040     case 10:
8041     case 11:
8042     case 12:
8043     case 14:
8044     case 15:
8045        do_FRINT (cpu);
8046        return;
8047
8048     case 7:
8049       if (INSTR (22, 22))
8050         do_FCVT_double_to_half (cpu);
8051       else
8052         do_FCVT_single_to_half (cpu);
8053       return;
8054
8055     case 13:
8056       HALT_NYI;
8057
8058     default:
8059       HALT_UNALLOC;
8060     }
8061 }
8062
8063 /* 32 bit signed int to float.  */
8064 static void
8065 scvtf32 (sim_cpu *cpu)
8066 {
8067   unsigned rn = INSTR (9, 5);
8068   unsigned sd = INSTR (4, 0);
8069
8070   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8071   aarch64_set_FP_float
8072     (cpu, sd, (float) aarch64_get_reg_s32 (cpu, rn, NO_SP));
8073 }
8074
8075 /* signed int to float.  */
8076 static void
8077 scvtf (sim_cpu *cpu)
8078 {
8079   unsigned rn = INSTR (9, 5);
8080   unsigned sd = INSTR (4, 0);
8081
8082   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8083   aarch64_set_FP_float
8084     (cpu, sd, (float) aarch64_get_reg_s64 (cpu, rn, NO_SP));
8085 }
8086
8087 /* 32 bit signed int to double.  */
8088 static void
8089 scvtd32 (sim_cpu *cpu)
8090 {
8091   unsigned rn = INSTR (9, 5);
8092   unsigned sd = INSTR (4, 0);
8093
8094   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8095   aarch64_set_FP_double
8096     (cpu, sd, (double) aarch64_get_reg_s32 (cpu, rn, NO_SP));
8097 }
8098
8099 /* signed int to double.  */
8100 static void
8101 scvtd (sim_cpu *cpu)
8102 {
8103   unsigned rn = INSTR (9, 5);
8104   unsigned sd = INSTR (4, 0);
8105
8106   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8107   aarch64_set_FP_double
8108     (cpu, sd, (double) aarch64_get_reg_s64 (cpu, rn, NO_SP));
8109 }
8110
8111 static const float  FLOAT_INT_MAX   = (float)  INT_MAX;
8112 static const float  FLOAT_INT_MIN   = (float)  INT_MIN;
8113 static const double DOUBLE_INT_MAX  = (double) INT_MAX;
8114 static const double DOUBLE_INT_MIN  = (double) INT_MIN;
8115 static const float  FLOAT_LONG_MAX  = (float)  LONG_MAX;
8116 static const float  FLOAT_LONG_MIN  = (float)  LONG_MIN;
8117 static const double DOUBLE_LONG_MAX = (double) LONG_MAX;
8118 static const double DOUBLE_LONG_MIN = (double) LONG_MIN;
8119
8120 /* Check for FP exception conditions:
8121      NaN raises IO
8122      Infinity raises IO
8123      Out of Range raises IO and IX and saturates value
8124      Denormal raises ID and IX and sets to zero.  */
8125 #define RAISE_EXCEPTIONS(F, VALUE, FTYPE, ITYPE)        \
8126   do                                                    \
8127     {                                                   \
8128       switch (fpclassify (F))                           \
8129         {                                               \
8130         case FP_INFINITE:                               \
8131         case FP_NAN:                                    \
8132           aarch64_set_FPSR (cpu, IO);                   \
8133           if (signbit (F))                              \
8134             VALUE = ITYPE##_MAX;                        \
8135           else                                          \
8136             VALUE = ITYPE##_MIN;                        \
8137           break;                                        \
8138                                                         \
8139         case FP_NORMAL:                                 \
8140           if (F >= FTYPE##_##ITYPE##_MAX)               \
8141             {                                           \
8142               aarch64_set_FPSR_bits (cpu, IO | IX, IO | IX);    \
8143               VALUE = ITYPE##_MAX;                      \
8144             }                                           \
8145           else if (F <= FTYPE##_##ITYPE##_MIN)          \
8146             {                                           \
8147               aarch64_set_FPSR_bits (cpu, IO | IX, IO | IX);    \
8148               VALUE = ITYPE##_MIN;                      \
8149             }                                           \
8150           break;                                        \
8151                                                         \
8152         case FP_SUBNORMAL:                              \
8153           aarch64_set_FPSR_bits (cpu, IO | IX | ID, IX | ID);   \
8154           VALUE = 0;                                    \
8155           break;                                        \
8156                                                         \
8157         default:                                        \
8158         case FP_ZERO:                                   \
8159           VALUE = 0;                                    \
8160           break;                                        \
8161         }                                               \
8162     }                                                   \
8163   while (0)
8164
8165 /* 32 bit convert float to signed int truncate towards zero.  */
8166 static void
8167 fcvtszs32 (sim_cpu *cpu)
8168 {
8169   unsigned sn = INSTR (9, 5);
8170   unsigned rd = INSTR (4, 0);
8171   /* TODO : check that this rounds toward zero.  */
8172   float   f = aarch64_get_FP_float (cpu, sn);
8173   int32_t value = (int32_t) f;
8174
8175   RAISE_EXCEPTIONS (f, value, FLOAT, INT);
8176
8177   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8178   /* Avoid sign extension to 64 bit.  */
8179   aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) value);
8180 }
8181
8182 /* 64 bit convert float to signed int truncate towards zero.  */
8183 static void
8184 fcvtszs (sim_cpu *cpu)
8185 {
8186   unsigned sn = INSTR (9, 5);
8187   unsigned rd = INSTR (4, 0);
8188   float f = aarch64_get_FP_float (cpu, sn);
8189   int64_t value = (int64_t) f;
8190
8191   RAISE_EXCEPTIONS (f, value, FLOAT, LONG);
8192
8193   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8194   aarch64_set_reg_s64 (cpu, rd, NO_SP, value);
8195 }
8196
8197 /* 32 bit convert double to signed int truncate towards zero.  */
8198 static void
8199 fcvtszd32 (sim_cpu *cpu)
8200 {
8201   unsigned sn = INSTR (9, 5);
8202   unsigned rd = INSTR (4, 0);
8203   /* TODO : check that this rounds toward zero.  */
8204   double   d = aarch64_get_FP_double (cpu, sn);
8205   int32_t  value = (int32_t) d;
8206
8207   RAISE_EXCEPTIONS (d, value, DOUBLE, INT);
8208
8209   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8210   /* Avoid sign extension to 64 bit.  */
8211   aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) value);
8212 }
8213
8214 /* 64 bit convert double to signed int truncate towards zero.  */
8215 static void
8216 fcvtszd (sim_cpu *cpu)
8217 {
8218   unsigned sn = INSTR (9, 5);
8219   unsigned rd = INSTR (4, 0);
8220   /* TODO : check that this rounds toward zero.  */
8221   double  d = aarch64_get_FP_double (cpu, sn);
8222   int64_t value;
8223
8224   value = (int64_t) d;
8225
8226   RAISE_EXCEPTIONS (d, value, DOUBLE, LONG);
8227
8228   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8229   aarch64_set_reg_s64 (cpu, rd, NO_SP, value);
8230 }
8231
8232 static void
8233 do_fcvtzu (sim_cpu *cpu)
8234 {
8235   /* instr[31]    = size: 32-bit (0), 64-bit (1)
8236      instr[30,23] = 00111100
8237      instr[22]    = type: single (0)/ double (1)
8238      instr[21]    = enable (0)/disable(1) precision
8239      instr[20,16] = 11001
8240      instr[15,10] = precision
8241      instr[9,5]   = Rs
8242      instr[4,0]   = Rd.  */
8243
8244   unsigned rs = INSTR (9, 5);
8245   unsigned rd = INSTR (4, 0);
8246
8247   NYI_assert (30, 23, 0x3C);
8248   NYI_assert (20, 16, 0x19);
8249
8250   if (INSTR (21, 21) != 1)
8251     /* Convert to fixed point.  */
8252     HALT_NYI;
8253
8254   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8255   if (INSTR (31, 31))
8256     {
8257       /* Convert to unsigned 64-bit integer.  */
8258       if (INSTR (22, 22))
8259         {
8260           double  d = aarch64_get_FP_double (cpu, rs);
8261           uint64_t value = (uint64_t) d;
8262
8263           /* Do not raise an exception if we have reached ULONG_MAX.  */
8264           if (value != (1UL << 63))
8265             RAISE_EXCEPTIONS (d, value, DOUBLE, LONG);
8266
8267           aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
8268         }
8269       else
8270         {
8271           float  f = aarch64_get_FP_float (cpu, rs);
8272           uint64_t value = (uint64_t) f;
8273
8274           /* Do not raise an exception if we have reached ULONG_MAX.  */
8275           if (value != (1UL << 63))
8276             RAISE_EXCEPTIONS (f, value, FLOAT, LONG);
8277
8278           aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
8279         }
8280     }
8281   else
8282     {
8283       uint32_t value;
8284
8285       /* Convert to unsigned 32-bit integer.  */
8286       if (INSTR (22, 22))
8287         {
8288           double  d = aarch64_get_FP_double (cpu, rs);
8289
8290           value = (uint32_t) d;
8291           /* Do not raise an exception if we have reached UINT_MAX.  */
8292           if (value != (1UL << 31))
8293             RAISE_EXCEPTIONS (d, value, DOUBLE, INT);
8294         }
8295       else
8296         {
8297           float  f = aarch64_get_FP_float (cpu, rs);
8298
8299           value = (uint32_t) f;
8300           /* Do not raise an exception if we have reached UINT_MAX.  */
8301           if (value != (1UL << 31))
8302             RAISE_EXCEPTIONS (f, value, FLOAT, INT);
8303         }
8304
8305       aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
8306     }
8307 }
8308
8309 static void
8310 do_UCVTF (sim_cpu *cpu)
8311 {
8312   /* instr[31]    = size: 32-bit (0), 64-bit (1)
8313      instr[30,23] = 001 1110 0
8314      instr[22]    = type: single (0)/ double (1)
8315      instr[21]    = enable (0)/disable(1) precision
8316      instr[20,16] = 0 0011
8317      instr[15,10] = precision
8318      instr[9,5]   = Rs
8319      instr[4,0]   = Rd.  */
8320
8321   unsigned rs = INSTR (9, 5);
8322   unsigned rd = INSTR (4, 0);
8323
8324   NYI_assert (30, 23, 0x3C);
8325   NYI_assert (20, 16, 0x03);
8326
8327   if (INSTR (21, 21) != 1)
8328     HALT_NYI;
8329
8330   /* FIXME: Add exception raising.  */
8331   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8332   if (INSTR (31, 31))
8333     {
8334       uint64_t value = aarch64_get_reg_u64 (cpu, rs, NO_SP);
8335
8336       if (INSTR (22, 22))
8337         aarch64_set_FP_double (cpu, rd, (double) value);
8338       else
8339         aarch64_set_FP_float (cpu, rd, (float) value);
8340     }
8341   else
8342     {
8343       uint32_t value =  aarch64_get_reg_u32 (cpu, rs, NO_SP);
8344
8345       if (INSTR (22, 22))
8346         aarch64_set_FP_double (cpu, rd, (double) value);
8347       else
8348         aarch64_set_FP_float (cpu, rd, (float) value);
8349     }
8350 }
8351
8352 static void
8353 float_vector_move (sim_cpu *cpu)
8354 {
8355   /* instr[31,17] == 100 1111 0101 0111
8356      instr[16]    ==> direction 0=> to GR, 1=> from GR
8357      instr[15,10] => ???
8358      instr[9,5]   ==> source
8359      instr[4,0]   ==> dest.  */
8360
8361   unsigned rn = INSTR (9, 5);
8362   unsigned rd = INSTR (4, 0);
8363
8364   NYI_assert (31, 17, 0x4F57);
8365
8366   if (INSTR (15, 10) != 0)
8367     HALT_UNALLOC;
8368
8369   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8370   if (INSTR (16, 16))
8371     aarch64_set_vec_u64 (cpu, rd, 1, aarch64_get_reg_u64 (cpu, rn, NO_SP));
8372   else
8373     aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u64 (cpu, rn, 1));
8374 }
8375
8376 static void
8377 dexSimpleFPIntegerConvert (sim_cpu *cpu)
8378 {
8379   /* instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
8380      instr[30     = 0
8381      instr[29]    = S :  0 ==> OK, 1 ==> UNALLOC
8382      instr[28,25] = 1111
8383      instr[24]    = 0
8384      instr[23,22] = type : 00 ==> single, 01 ==> double, 1x ==> UNALLOC
8385      instr[21]    = 1
8386      instr[20,19] = rmode
8387      instr[18,16] = opcode
8388      instr[15,10] = 10 0000  */
8389
8390   uint32_t rmode_opcode;
8391   uint32_t size_type;
8392   uint32_t type;
8393   uint32_t size;
8394   uint32_t S;
8395
8396   if (INSTR (31, 17) == 0x4F57)
8397     {
8398       float_vector_move (cpu);
8399       return;
8400     }
8401
8402   size = INSTR (31, 31);
8403   S = INSTR (29, 29);
8404   if (S != 0)
8405     HALT_UNALLOC;
8406
8407   type = INSTR (23, 22);
8408   if (type > 1)
8409     HALT_UNALLOC;
8410
8411   rmode_opcode = INSTR (20, 16);
8412   size_type = (size << 1) | type; /* 0==32f, 1==32d, 2==64f, 3==64d.  */
8413
8414   switch (rmode_opcode)
8415     {
8416     case 2:                     /* SCVTF.  */
8417       switch (size_type)
8418         {
8419         case 0: scvtf32 (cpu); return;
8420         case 1: scvtd32 (cpu); return;
8421         case 2: scvtf (cpu); return;
8422         case 3: scvtd (cpu); return;
8423         }
8424
8425     case 6:                     /* FMOV GR, Vec.  */
8426       switch (size_type)
8427         {
8428         case 0:  gfmovs (cpu); return;
8429         case 3:  gfmovd (cpu); return;
8430         default: HALT_UNALLOC;
8431         }
8432
8433     case 7:                     /* FMOV vec, GR.  */
8434       switch (size_type)
8435         {
8436         case 0:  fgmovs (cpu); return;
8437         case 3:  fgmovd (cpu); return;
8438         default: HALT_UNALLOC;
8439         }
8440
8441     case 24:                    /* FCVTZS.  */
8442       switch (size_type)
8443         {
8444         case 0: fcvtszs32 (cpu); return;
8445         case 1: fcvtszd32 (cpu); return;
8446         case 2: fcvtszs (cpu); return;
8447         case 3: fcvtszd (cpu); return;
8448         }
8449
8450     case 25: do_fcvtzu (cpu); return;
8451     case 3:  do_UCVTF (cpu); return;
8452
8453     case 0:     /* FCVTNS.  */
8454     case 1:     /* FCVTNU.  */
8455     case 4:     /* FCVTAS.  */
8456     case 5:     /* FCVTAU.  */
8457     case 8:     /* FCVPTS.  */
8458     case 9:     /* FCVTPU.  */
8459     case 16:    /* FCVTMS.  */
8460     case 17:    /* FCVTMU.  */
8461     default:
8462       HALT_NYI;
8463     }
8464 }
8465
8466 static void
8467 set_flags_for_float_compare (sim_cpu *cpu, float fvalue1, float fvalue2)
8468 {
8469   uint32_t flags;
8470
8471   /* FIXME: Add exception raising.  */
8472   if (isnan (fvalue1) || isnan (fvalue2))
8473     flags = C|V;
8474   else if (isinf (fvalue1) && isinf (fvalue2))
8475     {
8476       /* Subtracting two infinities may give a NaN.  We only need to compare
8477          the signs, which we can get from isinf.  */
8478       int result = isinf (fvalue1) - isinf (fvalue2);
8479
8480       if (result == 0)
8481         flags = Z|C;
8482       else if (result < 0)
8483         flags = N;
8484       else /* (result > 0).  */
8485         flags = C;
8486     }
8487   else
8488     {
8489       float result = fvalue1 - fvalue2;
8490
8491       if (result == 0.0)
8492         flags = Z|C;
8493       else if (result < 0)
8494         flags = N;
8495       else /* (result > 0).  */
8496         flags = C;
8497     }
8498
8499   aarch64_set_CPSR (cpu, flags);
8500 }
8501
8502 static void
8503 fcmps (sim_cpu *cpu)
8504 {
8505   unsigned sm = INSTR (20, 16);
8506   unsigned sn = INSTR ( 9,  5);
8507
8508   float fvalue1 = aarch64_get_FP_float (cpu, sn);
8509   float fvalue2 = aarch64_get_FP_float (cpu, sm);
8510
8511   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8512   set_flags_for_float_compare (cpu, fvalue1, fvalue2);
8513 }
8514
8515 /* Float compare to zero -- Invalid Operation exception
8516    only on signaling NaNs.  */
8517 static void
8518 fcmpzs (sim_cpu *cpu)
8519 {
8520   unsigned sn = INSTR ( 9,  5);
8521   float fvalue1 = aarch64_get_FP_float (cpu, sn);
8522
8523   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8524   set_flags_for_float_compare (cpu, fvalue1, 0.0f);
8525 }
8526
8527 /* Float compare -- Invalid Operation exception on all NaNs.  */
8528 static void
8529 fcmpes (sim_cpu *cpu)
8530 {
8531   unsigned sm = INSTR (20, 16);
8532   unsigned sn = INSTR ( 9,  5);
8533
8534   float fvalue1 = aarch64_get_FP_float (cpu, sn);
8535   float fvalue2 = aarch64_get_FP_float (cpu, sm);
8536
8537   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8538   set_flags_for_float_compare (cpu, fvalue1, fvalue2);
8539 }
8540
8541 /* Float compare to zero -- Invalid Operation exception on all NaNs.  */
8542 static void
8543 fcmpzes (sim_cpu *cpu)
8544 {
8545   unsigned sn = INSTR ( 9,  5);
8546   float fvalue1 = aarch64_get_FP_float (cpu, sn);
8547
8548   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8549   set_flags_for_float_compare (cpu, fvalue1, 0.0f);
8550 }
8551
8552 static void
8553 set_flags_for_double_compare (sim_cpu *cpu, double dval1, double dval2)
8554 {
8555   uint32_t flags;
8556
8557   /* FIXME: Add exception raising.  */
8558   if (isnan (dval1) || isnan (dval2))
8559     flags = C|V;
8560   else if (isinf (dval1) && isinf (dval2))
8561     {
8562       /* Subtracting two infinities may give a NaN.  We only need to compare
8563          the signs, which we can get from isinf.  */
8564       int result = isinf (dval1) - isinf (dval2);
8565
8566       if (result == 0)
8567         flags = Z|C;
8568       else if (result < 0)
8569         flags = N;
8570       else /* (result > 0).  */
8571         flags = C;
8572     }
8573   else
8574     {
8575       double result = dval1 - dval2;
8576
8577       if (result == 0.0)
8578         flags = Z|C;
8579       else if (result < 0)
8580         flags = N;
8581       else /* (result > 0).  */
8582         flags = C;
8583     }
8584
8585   aarch64_set_CPSR (cpu, flags);
8586 }
8587
8588 /* Double compare -- Invalid Operation exception only on signaling NaNs.  */
8589 static void
8590 fcmpd (sim_cpu *cpu)
8591 {
8592   unsigned sm = INSTR (20, 16);
8593   unsigned sn = INSTR ( 9,  5);
8594
8595   double dvalue1 = aarch64_get_FP_double (cpu, sn);
8596   double dvalue2 = aarch64_get_FP_double (cpu, sm);
8597
8598   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8599   set_flags_for_double_compare (cpu, dvalue1, dvalue2);
8600 }
8601
8602 /* Double compare to zero -- Invalid Operation exception
8603    only on signaling NaNs.  */
8604 static void
8605 fcmpzd (sim_cpu *cpu)
8606 {
8607   unsigned sn = INSTR ( 9,  5);
8608   double dvalue1 = aarch64_get_FP_double (cpu, sn);
8609
8610   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8611   set_flags_for_double_compare (cpu, dvalue1, 0.0);
8612 }
8613
8614 /* Double compare -- Invalid Operation exception on all NaNs.  */
8615 static void
8616 fcmped (sim_cpu *cpu)
8617 {
8618   unsigned sm = INSTR (20, 16);
8619   unsigned sn = INSTR ( 9,  5);
8620
8621   double dvalue1 = aarch64_get_FP_double (cpu, sn);
8622   double dvalue2 = aarch64_get_FP_double (cpu, sm);
8623
8624   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8625   set_flags_for_double_compare (cpu, dvalue1, dvalue2);
8626 }
8627
8628 /* Double compare to zero -- Invalid Operation exception on all NaNs.  */
8629 static void
8630 fcmpzed (sim_cpu *cpu)
8631 {
8632   unsigned sn = INSTR ( 9,  5);
8633   double dvalue1 = aarch64_get_FP_double (cpu, sn);
8634
8635   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8636   set_flags_for_double_compare (cpu, dvalue1, 0.0);
8637 }
8638
8639 static void
8640 dexSimpleFPCompare (sim_cpu *cpu)
8641 {
8642   /* assert instr[28,25] == 1111
8643      instr[30:24:21:13,10] = 0011000
8644      instr[31] = M : 0 ==> OK, 1 ==> UNALLOC
8645      instr[29] ==> S :  0 ==> OK, 1 ==> UNALLOC
8646      instr[23,22] ==> type : 0 ==> single, 01 ==> double, 1x ==> UNALLOC
8647      instr[15,14] ==> op : 00 ==> OK, ow ==> UNALLOC
8648      instr[4,0] ==> opcode2 : 00000 ==> FCMP, 10000 ==> FCMPE,
8649                               01000 ==> FCMPZ, 11000 ==> FCMPEZ,
8650                               ow ==> UNALLOC  */
8651   uint32_t dispatch;
8652   uint32_t M_S = (INSTR (31, 31) << 1) | INSTR (29, 29);
8653   uint32_t type = INSTR (23, 22);
8654   uint32_t op = INSTR (15, 14);
8655   uint32_t op2_2_0 = INSTR (2, 0);
8656
8657   if (op2_2_0 != 0)
8658     HALT_UNALLOC;
8659
8660   if (M_S != 0)
8661     HALT_UNALLOC;
8662
8663   if (type > 1)
8664     HALT_UNALLOC;
8665
8666   if (op != 0)
8667     HALT_UNALLOC;
8668
8669   /* dispatch on type and top 2 bits of opcode.  */
8670   dispatch = (type << 2) | INSTR (4, 3);
8671
8672   switch (dispatch)
8673     {
8674     case 0: fcmps (cpu); return;
8675     case 1: fcmpzs (cpu); return;
8676     case 2: fcmpes (cpu); return;
8677     case 3: fcmpzes (cpu); return;
8678     case 4: fcmpd (cpu); return;
8679     case 5: fcmpzd (cpu); return;
8680     case 6: fcmped (cpu); return;
8681     case 7: fcmpzed (cpu); return;
8682     }
8683 }
8684
8685 static void
8686 do_scalar_FADDP (sim_cpu *cpu)
8687 {
8688   /* instr [31,23] = 0111 1110 0
8689      instr [22]    = single(0)/double(1)
8690      instr [21,10] = 11 0000 1101 10
8691      instr [9,5]   = Fn
8692      instr [4,0]   = Fd.  */
8693
8694   unsigned Fn = INSTR (9, 5);
8695   unsigned Fd = INSTR (4, 0);
8696
8697   NYI_assert (31, 23, 0x0FC);
8698   NYI_assert (21, 10, 0xC36);
8699
8700   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8701   if (INSTR (22, 22))
8702     {
8703       double val1 = aarch64_get_vec_double (cpu, Fn, 0);
8704       double val2 = aarch64_get_vec_double (cpu, Fn, 1);
8705
8706       aarch64_set_FP_double (cpu, Fd, val1 + val2);
8707     }
8708   else
8709     {
8710       float val1 = aarch64_get_vec_float (cpu, Fn, 0);
8711       float val2 = aarch64_get_vec_float (cpu, Fn, 1);
8712
8713       aarch64_set_FP_float (cpu, Fd, val1 + val2);
8714     }
8715 }
8716
8717 /* Floating point absolute difference.  */
8718
8719 static void
8720 do_scalar_FABD (sim_cpu *cpu)
8721 {
8722   /* instr [31,23] = 0111 1110 1
8723      instr [22]    = float(0)/double(1)
8724      instr [21]    = 1
8725      instr [20,16] = Rm
8726      instr [15,10] = 1101 01
8727      instr [9, 5]  = Rn
8728      instr [4, 0]  = Rd.  */
8729
8730   unsigned rm = INSTR (20, 16);
8731   unsigned rn = INSTR (9, 5);
8732   unsigned rd = INSTR (4, 0);
8733
8734   NYI_assert (31, 23, 0x0FD);
8735   NYI_assert (21, 21, 1);
8736   NYI_assert (15, 10, 0x35);
8737
8738   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8739   if (INSTR (22, 22))
8740     aarch64_set_FP_double (cpu, rd,
8741                            fabs (aarch64_get_FP_double (cpu, rn)
8742                                  - aarch64_get_FP_double (cpu, rm)));
8743   else
8744     aarch64_set_FP_float (cpu, rd,
8745                           fabsf (aarch64_get_FP_float (cpu, rn)
8746                                  - aarch64_get_FP_float (cpu, rm)));
8747 }
8748
8749 static void
8750 do_scalar_CMGT (sim_cpu *cpu)
8751 {
8752   /* instr [31,21] = 0101 1110 111
8753      instr [20,16] = Rm
8754      instr [15,10] = 00 1101
8755      instr [9, 5]  = Rn
8756      instr [4, 0]  = Rd.  */
8757
8758   unsigned rm = INSTR (20, 16);
8759   unsigned rn = INSTR (9, 5);
8760   unsigned rd = INSTR (4, 0);
8761
8762   NYI_assert (31, 21, 0x2F7);
8763   NYI_assert (15, 10, 0x0D);
8764
8765   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8766   aarch64_set_vec_u64 (cpu, rd, 0,
8767                        aarch64_get_vec_u64 (cpu, rn, 0) >
8768                        aarch64_get_vec_u64 (cpu, rm, 0) ? -1L : 0L);
8769 }
8770
8771 static void
8772 do_scalar_USHR (sim_cpu *cpu)
8773 {
8774   /* instr [31,23] = 0111 1111 0
8775      instr [22,16] = shift amount
8776      instr [15,10] = 0000 01
8777      instr [9, 5]  = Rn
8778      instr [4, 0]  = Rd.  */
8779
8780   unsigned amount = 128 - INSTR (22, 16);
8781   unsigned rn = INSTR (9, 5);
8782   unsigned rd = INSTR (4, 0);
8783
8784   NYI_assert (31, 23, 0x0FE);
8785   NYI_assert (15, 10, 0x01);
8786
8787   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8788   aarch64_set_vec_u64 (cpu, rd, 0,
8789                        aarch64_get_vec_u64 (cpu, rn, 0) >> amount);
8790 }
8791
8792 static void
8793 do_scalar_SSHL (sim_cpu *cpu)
8794 {
8795   /* instr [31,21] = 0101 1110 111
8796      instr [20,16] = Rm
8797      instr [15,10] = 0100 01
8798      instr [9, 5]  = Rn
8799      instr [4, 0]  = Rd.  */
8800
8801   unsigned rm = INSTR (20, 16);
8802   unsigned rn = INSTR (9, 5);
8803   unsigned rd = INSTR (4, 0);
8804   signed int shift = aarch64_get_vec_s8 (cpu, rm, 0);
8805
8806   NYI_assert (31, 21, 0x2F7);
8807   NYI_assert (15, 10, 0x11);
8808
8809   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8810   if (shift >= 0)
8811     aarch64_set_vec_s64 (cpu, rd, 0,
8812                          aarch64_get_vec_s64 (cpu, rn, 0) << shift);
8813   else
8814     aarch64_set_vec_s64 (cpu, rd, 0,
8815                          aarch64_get_vec_s64 (cpu, rn, 0) >> - shift);
8816 }
8817
8818 static void
8819 do_scalar_shift (sim_cpu *cpu)
8820 {
8821   /* instr [31,23] = 0101 1111 0
8822      instr [22,16] = shift amount
8823      instr [15,10] = 0101 01   [SHL]
8824      instr [15,10] = 0000 01   [SSHR]
8825      instr [9, 5]  = Rn
8826      instr [4, 0]  = Rd.  */
8827
8828   unsigned rn = INSTR (9, 5);
8829   unsigned rd = INSTR (4, 0);
8830   unsigned amount;
8831
8832   NYI_assert (31, 23, 0x0BE);
8833
8834   if (INSTR (22, 22) == 0)
8835     HALT_UNALLOC;
8836
8837   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8838   switch (INSTR (15, 10))
8839     {
8840     case 0x01: /* SSHR */
8841       amount = 128 - INSTR (22, 16);
8842       aarch64_set_vec_s64 (cpu, rd, 0,
8843                            aarch64_get_vec_s64 (cpu, rn, 0) >> amount);
8844       return;
8845     case 0x15: /* SHL */
8846       amount = INSTR (22, 16) - 64;
8847       aarch64_set_vec_u64 (cpu, rd, 0,
8848                            aarch64_get_vec_u64 (cpu, rn, 0) << amount);
8849       return;
8850     default:
8851       HALT_NYI;
8852     }
8853 }
8854
8855 /* FCMEQ FCMGT FCMGE.  */
8856 static void
8857 do_scalar_FCM (sim_cpu *cpu)
8858 {
8859   /* instr [31,30] = 01
8860      instr [29]    = U
8861      instr [28,24] = 1 1110
8862      instr [23]    = E
8863      instr [22]    = size
8864      instr [21]    = 1
8865      instr [20,16] = Rm
8866      instr [15,12] = 1110
8867      instr [11]    = AC
8868      instr [10]    = 1
8869      instr [9, 5]  = Rn
8870      instr [4, 0]  = Rd.  */
8871
8872   unsigned rm = INSTR (20, 16);
8873   unsigned rn = INSTR (9, 5);
8874   unsigned rd = INSTR (4, 0);
8875   unsigned EUac = (INSTR (23, 23) << 2) | (INSTR (29, 29) << 1) | INSTR (11, 11);
8876   unsigned result;
8877   float val1;
8878   float val2;
8879
8880   NYI_assert (31, 30, 1);
8881   NYI_assert (28, 24, 0x1E);
8882   NYI_assert (21, 21, 1);
8883   NYI_assert (15, 12, 0xE);
8884   NYI_assert (10, 10, 1);
8885
8886   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8887   if (INSTR (22, 22))
8888     {
8889       double val1 = aarch64_get_FP_double (cpu, rn);
8890       double val2 = aarch64_get_FP_double (cpu, rm);
8891
8892       switch (EUac)
8893         {
8894         case 0: /* 000 */
8895           result = val1 == val2;
8896           break;
8897
8898         case 3: /* 011 */
8899           val1 = fabs (val1);
8900           val2 = fabs (val2);
8901           /* Fall through. */
8902         case 2: /* 010 */
8903           result = val1 >= val2;
8904           break;
8905
8906         case 7: /* 111 */
8907           val1 = fabs (val1);
8908           val2 = fabs (val2);
8909           /* Fall through. */
8910         case 6: /* 110 */
8911           result = val1 > val2;
8912           break;
8913
8914         default:
8915           HALT_UNALLOC;
8916         }
8917
8918       aarch64_set_vec_u32 (cpu, rd, 0, result ? -1 : 0);
8919       return;
8920     }
8921
8922   val1 = aarch64_get_FP_float (cpu, rn);
8923   val2 = aarch64_get_FP_float (cpu, rm);
8924
8925   switch (EUac)
8926     {
8927     case 0: /* 000 */
8928       result = val1 == val2;
8929       break;
8930
8931     case 3: /* 011 */
8932       val1 = fabsf (val1);
8933       val2 = fabsf (val2);
8934       /* Fall through. */
8935     case 2: /* 010 */
8936       result = val1 >= val2;
8937       break;
8938
8939     case 7: /* 111 */
8940       val1 = fabsf (val1);
8941       val2 = fabsf (val2);
8942       /* Fall through. */
8943     case 6: /* 110 */
8944       result = val1 > val2;
8945       break;
8946
8947     default:
8948       HALT_UNALLOC;
8949     }
8950
8951   aarch64_set_vec_u32 (cpu, rd, 0, result ? -1 : 0);
8952 }
8953
8954 /* An alias of DUP.  */
8955 static void
8956 do_scalar_MOV (sim_cpu *cpu)
8957 {
8958   /* instr [31,21] = 0101 1110 000
8959      instr [20,16] = imm5
8960      instr [15,10] = 0000 01
8961      instr [9, 5]  = Rn
8962      instr [4, 0]  = Rd.  */
8963
8964   unsigned rn = INSTR (9, 5);
8965   unsigned rd = INSTR (4, 0);
8966   unsigned index;
8967
8968   NYI_assert (31, 21, 0x2F0);
8969   NYI_assert (15, 10, 0x01);
8970
8971   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
8972   if (INSTR (16, 16))
8973     {
8974       /* 8-bit.  */
8975       index = INSTR (20, 17);
8976       aarch64_set_vec_u8
8977         (cpu, rd, 0, aarch64_get_vec_u8 (cpu, rn, index));
8978     }
8979   else if (INSTR (17, 17))
8980     {
8981       /* 16-bit.  */
8982       index = INSTR (20, 18);
8983       aarch64_set_vec_u16
8984         (cpu, rd, 0, aarch64_get_vec_u16 (cpu, rn, index));
8985     }
8986   else if (INSTR (18, 18))
8987     {
8988       /* 32-bit.  */
8989       index = INSTR (20, 19);
8990       aarch64_set_vec_u32
8991         (cpu, rd, 0, aarch64_get_vec_u32 (cpu, rn, index));
8992     }
8993   else if (INSTR (19, 19))
8994     {
8995       /* 64-bit.  */
8996       index = INSTR (20, 20);
8997       aarch64_set_vec_u64
8998         (cpu, rd, 0, aarch64_get_vec_u64 (cpu, rn, index));
8999     }
9000   else
9001     HALT_UNALLOC;
9002 }
9003
9004 static void
9005 do_scalar_NEG (sim_cpu *cpu)
9006 {
9007   /* instr [31,10] = 0111 1110 1110 0000 1011 10
9008      instr [9, 5]  = Rn
9009      instr [4, 0]  = Rd.  */
9010
9011   unsigned rn = INSTR (9, 5);
9012   unsigned rd = INSTR (4, 0);
9013
9014   NYI_assert (31, 10, 0x1FB82E);
9015
9016   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9017   aarch64_set_vec_u64 (cpu, rd, 0, - aarch64_get_vec_u64 (cpu, rn, 0));
9018 }
9019
9020 static void
9021 do_scalar_USHL (sim_cpu *cpu)
9022 {
9023   /* instr [31,21] = 0111 1110 111
9024      instr [20,16] = Rm
9025      instr [15,10] = 0100 01
9026      instr [9, 5]  = Rn
9027      instr [4, 0]  = Rd.  */
9028
9029   unsigned rm = INSTR (20, 16);
9030   unsigned rn = INSTR (9, 5);
9031   unsigned rd = INSTR (4, 0);
9032   signed int shift = aarch64_get_vec_s8 (cpu, rm, 0);
9033
9034   NYI_assert (31, 21, 0x3F7);
9035   NYI_assert (15, 10, 0x11);
9036
9037   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9038   if (shift >= 0)
9039     aarch64_set_vec_u64 (cpu, rd, 0, aarch64_get_vec_u64 (cpu, rn, 0) << shift);
9040   else
9041     aarch64_set_vec_u64 (cpu, rd, 0, aarch64_get_vec_u64 (cpu, rn, 0) >> - shift);
9042 }
9043
9044 static void
9045 do_double_add (sim_cpu *cpu)
9046 {
9047   /* instr [31,21] = 0101 1110 111
9048      instr [20,16] = Fn
9049      instr [15,10] = 1000 01
9050      instr [9,5]   = Fm
9051      instr [4,0]   = Fd.  */
9052   unsigned Fd;
9053   unsigned Fm;
9054   unsigned Fn;
9055   double val1;
9056   double val2;
9057
9058   NYI_assert (31, 21, 0x2F7);
9059   NYI_assert (15, 10, 0x21);
9060
9061   Fd = INSTR (4, 0);
9062   Fm = INSTR (9, 5);
9063   Fn = INSTR (20, 16);
9064
9065   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9066   val1 = aarch64_get_FP_double (cpu, Fm);
9067   val2 = aarch64_get_FP_double (cpu, Fn);
9068
9069   aarch64_set_FP_double (cpu, Fd, val1 + val2);
9070 }
9071
9072 static void
9073 do_scalar_UCVTF (sim_cpu *cpu)
9074 {
9075   /* instr [31,23] = 0111 1110 0
9076      instr [22]    = single(0)/double(1)
9077      instr [21,10] = 10 0001 1101 10
9078      instr [9,5]   = rn
9079      instr [4,0]   = rd.  */
9080
9081   unsigned rn = INSTR (9, 5);
9082   unsigned rd = INSTR (4, 0);
9083
9084   NYI_assert (31, 23, 0x0FC);
9085   NYI_assert (21, 10, 0x876);
9086
9087   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9088   if (INSTR (22, 22))
9089     {
9090       uint64_t val = aarch64_get_vec_u64 (cpu, rn, 0);
9091
9092       aarch64_set_vec_double (cpu, rd, 0, (double) val);
9093     }
9094   else
9095     {
9096       uint32_t val = aarch64_get_vec_u32 (cpu, rn, 0);
9097
9098       aarch64_set_vec_float (cpu, rd, 0, (float) val);
9099     }
9100 }
9101
9102 static void
9103 do_scalar_vec (sim_cpu *cpu)
9104 {
9105   /* instr [30] = 1.  */
9106   /* instr [28,25] = 1111.  */
9107   switch (INSTR (31, 23))
9108     {
9109     case 0xBC:
9110       switch (INSTR (15, 10))
9111         {
9112         case 0x01: do_scalar_MOV (cpu); return;
9113         case 0x39: do_scalar_FCM (cpu); return;
9114         case 0x3B: do_scalar_FCM (cpu); return;
9115         }
9116       break;
9117
9118     case 0xBE: do_scalar_shift (cpu); return;
9119
9120     case 0xFC:
9121       switch (INSTR (15, 10))
9122         {
9123         case 0x36:
9124           switch (INSTR (21, 16))
9125             {
9126             case 0x30: do_scalar_FADDP (cpu); return;
9127             case 0x21: do_scalar_UCVTF (cpu); return;
9128             }
9129           HALT_NYI;
9130         case 0x39: do_scalar_FCM (cpu); return;
9131         case 0x3B: do_scalar_FCM (cpu); return;
9132         }
9133       break;
9134
9135     case 0xFD:
9136       switch (INSTR (15, 10))
9137         {
9138         case 0x0D: do_scalar_CMGT (cpu); return;
9139         case 0x11: do_scalar_USHL (cpu); return;
9140         case 0x2E: do_scalar_NEG (cpu); return;
9141         case 0x35: do_scalar_FABD (cpu); return;
9142         case 0x39: do_scalar_FCM (cpu); return;
9143         case 0x3B: do_scalar_FCM (cpu); return;
9144         default:
9145           HALT_NYI;
9146         }
9147
9148     case 0xFE: do_scalar_USHR (cpu); return;
9149
9150     case 0xBD:
9151       switch (INSTR (15, 10))
9152         {
9153         case 0x21: do_double_add (cpu); return;
9154         case 0x11: do_scalar_SSHL (cpu); return;
9155         default:
9156           HALT_NYI;
9157         }
9158
9159     default:
9160       HALT_NYI;
9161     }
9162 }
9163
9164 static void
9165 dexAdvSIMD1 (sim_cpu *cpu)
9166 {
9167   /* instr [28,25] = 1 111.  */
9168
9169   /* We are currently only interested in the basic
9170      scalar fp routines which all have bit 30 = 0.  */
9171   if (INSTR (30, 30))
9172     do_scalar_vec (cpu);
9173
9174   /* instr[24] is set for FP data processing 3-source and clear for
9175      all other basic scalar fp instruction groups.  */
9176   else if (INSTR (24, 24))
9177     dexSimpleFPDataProc3Source (cpu);
9178
9179   /* instr[21] is clear for floating <-> fixed conversions and set for
9180      all other basic scalar fp instruction groups.  */
9181   else if (!INSTR (21, 21))
9182     dexSimpleFPFixedConvert (cpu);
9183
9184   /* instr[11,10] : 01 ==> cond compare, 10 ==> Data Proc 2 Source
9185      11 ==> cond select,  00 ==> other.  */
9186   else
9187     switch (INSTR (11, 10))
9188       {
9189       case 1: dexSimpleFPCondCompare (cpu); return;
9190       case 2: dexSimpleFPDataProc2Source (cpu); return;
9191       case 3: dexSimpleFPCondSelect (cpu); return;
9192
9193       default:
9194         /* Now an ordered cascade of tests.
9195            FP immediate has instr [12] == 1.
9196            FP compare has   instr [13] == 1.
9197            FP Data Proc 1 Source has instr [14] == 1.
9198            FP floating <--> integer conversions has instr [15] == 0.  */
9199         if (INSTR (12, 12))
9200           dexSimpleFPImmediate (cpu);
9201
9202         else if (INSTR (13, 13))
9203           dexSimpleFPCompare (cpu);
9204
9205         else if (INSTR (14, 14))
9206           dexSimpleFPDataProc1Source (cpu);
9207
9208         else if (!INSTR (15, 15))
9209           dexSimpleFPIntegerConvert (cpu);
9210
9211         else
9212           /* If we get here then instr[15] == 1 which means UNALLOC.  */
9213           HALT_UNALLOC;
9214       }
9215 }
9216
9217 /* PC relative addressing.  */
9218
9219 static void
9220 pcadr (sim_cpu *cpu)
9221 {
9222   /* instr[31] = op : 0 ==> ADR, 1 ==> ADRP
9223      instr[30,29] = immlo
9224      instr[23,5] = immhi.  */
9225   uint64_t address;
9226   unsigned rd = INSTR (4, 0);
9227   uint32_t isPage = INSTR (31, 31);
9228   union { int64_t u64; uint64_t s64; } imm;
9229   uint64_t offset;
9230
9231   imm.s64 = simm64 (aarch64_get_instr (cpu), 23, 5);
9232   offset = imm.u64;
9233   offset = (offset << 2) | INSTR (30, 29);
9234
9235   address = aarch64_get_PC (cpu);
9236
9237   if (isPage)
9238     {
9239       offset <<= 12;
9240       address &= ~0xfff;
9241     }
9242
9243   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9244   aarch64_set_reg_u64 (cpu, rd, NO_SP, address + offset);
9245 }
9246
9247 /* Specific decode and execute for group Data Processing Immediate.  */
9248
9249 static void
9250 dexPCRelAddressing (sim_cpu *cpu)
9251 {
9252   /* assert instr[28,24] = 10000.  */
9253   pcadr (cpu);
9254 }
9255
9256 /* Immediate logical.
9257    The bimm32/64 argument is constructed by replicating a 2, 4, 8,
9258    16, 32 or 64 bit sequence pulled out at decode and possibly
9259    inverting it..
9260
9261    N.B. the output register (dest) can normally be Xn or SP
9262    the exception occurs for flag setting instructions which may
9263    only use Xn for the output (dest).  The input register can
9264    never be SP.  */
9265
9266 /* 32 bit and immediate.  */
9267 static void
9268 and32 (sim_cpu *cpu, uint32_t bimm)
9269 {
9270   unsigned rn = INSTR (9, 5);
9271   unsigned rd = INSTR (4, 0);
9272
9273   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9274   aarch64_set_reg_u64 (cpu, rd, SP_OK,
9275                        aarch64_get_reg_u32 (cpu, rn, NO_SP) & bimm);
9276 }
9277
9278 /* 64 bit and immediate.  */
9279 static void
9280 and64 (sim_cpu *cpu, uint64_t bimm)
9281 {
9282   unsigned rn = INSTR (9, 5);
9283   unsigned rd = INSTR (4, 0);
9284
9285   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9286   aarch64_set_reg_u64 (cpu, rd, SP_OK,
9287                        aarch64_get_reg_u64 (cpu, rn, NO_SP) & bimm);
9288 }
9289
9290 /* 32 bit and immediate set flags.  */
9291 static void
9292 ands32 (sim_cpu *cpu, uint32_t bimm)
9293 {
9294   unsigned rn = INSTR (9, 5);
9295   unsigned rd = INSTR (4, 0);
9296
9297   uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
9298   uint32_t value2 = bimm;
9299
9300   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9301   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
9302   set_flags_for_binop32 (cpu, value1 & value2);
9303 }
9304
9305 /* 64 bit and immediate set flags.  */
9306 static void
9307 ands64 (sim_cpu *cpu, uint64_t bimm)
9308 {
9309   unsigned rn = INSTR (9, 5);
9310   unsigned rd = INSTR (4, 0);
9311
9312   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
9313   uint64_t value2 = bimm;
9314
9315   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9316   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
9317   set_flags_for_binop64 (cpu, value1 & value2);
9318 }
9319
9320 /* 32 bit exclusive or immediate.  */
9321 static void
9322 eor32 (sim_cpu *cpu, uint32_t bimm)
9323 {
9324   unsigned rn = INSTR (9, 5);
9325   unsigned rd = INSTR (4, 0);
9326
9327   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9328   aarch64_set_reg_u64 (cpu, rd, SP_OK,
9329                        aarch64_get_reg_u32 (cpu, rn, NO_SP) ^ bimm);
9330 }
9331
9332 /* 64 bit exclusive or immediate.  */
9333 static void
9334 eor64 (sim_cpu *cpu, uint64_t bimm)
9335 {
9336   unsigned rn = INSTR (9, 5);
9337   unsigned rd = INSTR (4, 0);
9338
9339   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9340   aarch64_set_reg_u64 (cpu, rd, SP_OK,
9341                        aarch64_get_reg_u64 (cpu, rn, NO_SP) ^ bimm);
9342 }
9343
9344 /* 32 bit or immediate.  */
9345 static void
9346 orr32 (sim_cpu *cpu, uint32_t bimm)
9347 {
9348   unsigned rn = INSTR (9, 5);
9349   unsigned rd = INSTR (4, 0);
9350
9351   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9352   aarch64_set_reg_u64 (cpu, rd, SP_OK,
9353                        aarch64_get_reg_u32 (cpu, rn, NO_SP) | bimm);
9354 }
9355
9356 /* 64 bit or immediate.  */
9357 static void
9358 orr64 (sim_cpu *cpu, uint64_t bimm)
9359 {
9360   unsigned rn = INSTR (9, 5);
9361   unsigned rd = INSTR (4, 0);
9362
9363   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9364   aarch64_set_reg_u64 (cpu, rd, SP_OK,
9365                        aarch64_get_reg_u64 (cpu, rn, NO_SP) | bimm);
9366 }
9367
9368 /* Logical shifted register.
9369    These allow an optional LSL, ASR, LSR or ROR to the second source
9370    register with a count up to the register bit count.
9371    N.B register args may not be SP.  */
9372
9373 /* 32 bit AND shifted register.  */
9374 static void
9375 and32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9376 {
9377   unsigned rm = INSTR (20, 16);
9378   unsigned rn = INSTR (9, 5);
9379   unsigned rd = INSTR (4, 0);
9380
9381   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9382   aarch64_set_reg_u64
9383     (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
9384      & shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
9385 }
9386
9387 /* 64 bit AND shifted register.  */
9388 static void
9389 and64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9390 {
9391   unsigned rm = INSTR (20, 16);
9392   unsigned rn = INSTR (9, 5);
9393   unsigned rd = INSTR (4, 0);
9394
9395   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9396   aarch64_set_reg_u64
9397     (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
9398      & shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
9399 }
9400
9401 /* 32 bit AND shifted register setting flags.  */
9402 static void
9403 ands32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9404 {
9405   unsigned rm = INSTR (20, 16);
9406   unsigned rn = INSTR (9, 5);
9407   unsigned rd = INSTR (4, 0);
9408
9409   uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
9410   uint32_t value2 = shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
9411                                shift, count);
9412
9413   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9414   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
9415   set_flags_for_binop32 (cpu, value1 & value2);
9416 }
9417
9418 /* 64 bit AND shifted register setting flags.  */
9419 static void
9420 ands64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9421 {
9422   unsigned rm = INSTR (20, 16);
9423   unsigned rn = INSTR (9, 5);
9424   unsigned rd = INSTR (4, 0);
9425
9426   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
9427   uint64_t value2 = shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
9428                                shift, count);
9429
9430   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9431   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
9432   set_flags_for_binop64 (cpu, value1 & value2);
9433 }
9434
9435 /* 32 bit BIC shifted register.  */
9436 static void
9437 bic32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9438 {
9439   unsigned rm = INSTR (20, 16);
9440   unsigned rn = INSTR (9, 5);
9441   unsigned rd = INSTR (4, 0);
9442
9443   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9444   aarch64_set_reg_u64
9445     (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
9446      & ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
9447 }
9448
9449 /* 64 bit BIC shifted register.  */
9450 static void
9451 bic64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9452 {
9453   unsigned rm = INSTR (20, 16);
9454   unsigned rn = INSTR (9, 5);
9455   unsigned rd = INSTR (4, 0);
9456
9457   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9458   aarch64_set_reg_u64
9459     (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
9460      & ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
9461 }
9462
9463 /* 32 bit BIC shifted register setting flags.  */
9464 static void
9465 bics32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9466 {
9467   unsigned rm = INSTR (20, 16);
9468   unsigned rn = INSTR (9, 5);
9469   unsigned rd = INSTR (4, 0);
9470
9471   uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
9472   uint32_t value2 = ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP),
9473                                  shift, count);
9474
9475   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9476   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
9477   set_flags_for_binop32 (cpu, value1 & value2);
9478 }
9479
9480 /* 64 bit BIC shifted register setting flags.  */
9481 static void
9482 bics64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9483 {
9484   unsigned rm = INSTR (20, 16);
9485   unsigned rn = INSTR (9, 5);
9486   unsigned rd = INSTR (4, 0);
9487
9488   uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
9489   uint64_t value2 = ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP),
9490                                  shift, count);
9491
9492   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9493   aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2);
9494   set_flags_for_binop64 (cpu, value1 & value2);
9495 }
9496
9497 /* 32 bit EON shifted register.  */
9498 static void
9499 eon32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9500 {
9501   unsigned rm = INSTR (20, 16);
9502   unsigned rn = INSTR (9, 5);
9503   unsigned rd = INSTR (4, 0);
9504
9505   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9506   aarch64_set_reg_u64
9507     (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
9508      ^ ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
9509 }
9510
9511 /* 64 bit EON shifted register.  */
9512 static void
9513 eon64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9514 {
9515   unsigned rm = INSTR (20, 16);
9516   unsigned rn = INSTR (9, 5);
9517   unsigned rd = INSTR (4, 0);
9518
9519   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9520   aarch64_set_reg_u64
9521     (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
9522      ^ ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
9523 }
9524
9525 /* 32 bit EOR shifted register.  */
9526 static void
9527 eor32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9528 {
9529   unsigned rm = INSTR (20, 16);
9530   unsigned rn = INSTR (9, 5);
9531   unsigned rd = INSTR (4, 0);
9532
9533   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9534   aarch64_set_reg_u64
9535     (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
9536      ^ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
9537 }
9538
9539 /* 64 bit EOR shifted register.  */
9540 static void
9541 eor64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9542 {
9543   unsigned rm = INSTR (20, 16);
9544   unsigned rn = INSTR (9, 5);
9545   unsigned rd = INSTR (4, 0);
9546
9547   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9548   aarch64_set_reg_u64
9549     (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
9550      ^ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
9551 }
9552
9553 /* 32 bit ORR shifted register.  */
9554 static void
9555 orr32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9556 {
9557   unsigned rm = INSTR (20, 16);
9558   unsigned rn = INSTR (9, 5);
9559   unsigned rd = INSTR (4, 0);
9560
9561   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9562   aarch64_set_reg_u64
9563     (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
9564      | shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
9565 }
9566
9567 /* 64 bit ORR shifted register.  */
9568 static void
9569 orr64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9570 {
9571   unsigned rm = INSTR (20, 16);
9572   unsigned rn = INSTR (9, 5);
9573   unsigned rd = INSTR (4, 0);
9574
9575   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9576   aarch64_set_reg_u64
9577     (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
9578      | shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
9579 }
9580
9581 /* 32 bit ORN shifted register.  */
9582 static void
9583 orn32_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9584 {
9585   unsigned rm = INSTR (20, 16);
9586   unsigned rn = INSTR (9, 5);
9587   unsigned rd = INSTR (4, 0);
9588
9589   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9590   aarch64_set_reg_u64
9591     (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP)
9592      | ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count));
9593 }
9594
9595 /* 64 bit ORN shifted register.  */
9596 static void
9597 orn64_shift (sim_cpu *cpu, Shift shift, uint32_t count)
9598 {
9599   unsigned rm = INSTR (20, 16);
9600   unsigned rn = INSTR (9, 5);
9601   unsigned rd = INSTR (4, 0);
9602
9603   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9604   aarch64_set_reg_u64
9605     (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP)
9606      | ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count));
9607 }
9608
9609 static void
9610 dexLogicalImmediate (sim_cpu *cpu)
9611 {
9612   /* assert instr[28,23] = 1001000
9613      instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
9614      instr[30,29] = op : 0 ==> AND, 1 ==> ORR, 2 ==> EOR, 3 ==> ANDS
9615      instr[22] = N : used to construct immediate mask
9616      instr[21,16] = immr
9617      instr[15,10] = imms
9618      instr[9,5] = Rn
9619      instr[4,0] = Rd  */
9620
9621   /* 32 bit operations must have N = 0 or else we have an UNALLOC.  */
9622   uint32_t size = INSTR (31, 31);
9623   uint32_t N = INSTR (22, 22);
9624   /* uint32_t immr = INSTR (21, 16);.  */
9625   /* uint32_t imms = INSTR (15, 10);.  */
9626   uint32_t index = INSTR (22, 10);
9627   uint64_t bimm64 = LITable [index];
9628   uint32_t dispatch = INSTR (30, 29);
9629
9630   if (~size & N)
9631     HALT_UNALLOC;
9632
9633   if (!bimm64)
9634     HALT_UNALLOC;
9635
9636   if (size == 0)
9637     {
9638       uint32_t bimm = (uint32_t) bimm64;
9639
9640       switch (dispatch)
9641         {
9642         case 0: and32 (cpu, bimm); return;
9643         case 1: orr32 (cpu, bimm); return;
9644         case 2: eor32 (cpu, bimm); return;
9645         case 3: ands32 (cpu, bimm); return;
9646         }
9647     }
9648   else
9649     {
9650       switch (dispatch)
9651         {
9652         case 0: and64 (cpu, bimm64); return;
9653         case 1: orr64 (cpu, bimm64); return;
9654         case 2: eor64 (cpu, bimm64); return;
9655         case 3: ands64 (cpu, bimm64); return;
9656         }
9657     }
9658   HALT_UNALLOC;
9659 }
9660
9661 /* Immediate move.
9662    The uimm argument is a 16 bit value to be inserted into the
9663    target register the pos argument locates the 16 bit word in the
9664    dest register i.e. it is in {0, 1} for 32 bit and {0, 1, 2,
9665    3} for 64 bit.
9666    N.B register arg may not be SP so it should be.
9667    accessed using the setGZRegisterXXX accessors.  */
9668
9669 /* 32 bit move 16 bit immediate zero remaining shorts.  */
9670 static void
9671 movz32 (sim_cpu *cpu, uint32_t val, uint32_t pos)
9672 {
9673   unsigned rd = INSTR (4, 0);
9674
9675   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9676   aarch64_set_reg_u64 (cpu, rd, NO_SP, val << (pos * 16));
9677 }
9678
9679 /* 64 bit move 16 bit immediate zero remaining shorts.  */
9680 static void
9681 movz64 (sim_cpu *cpu, uint32_t val, uint32_t pos)
9682 {
9683   unsigned rd = INSTR (4, 0);
9684
9685   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9686   aarch64_set_reg_u64 (cpu, rd, NO_SP, ((uint64_t) val) << (pos * 16));
9687 }
9688
9689 /* 32 bit move 16 bit immediate negated.  */
9690 static void
9691 movn32 (sim_cpu *cpu, uint32_t val, uint32_t pos)
9692 {
9693   unsigned rd = INSTR (4, 0);
9694
9695   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9696   aarch64_set_reg_u64 (cpu, rd, NO_SP, ((val << (pos * 16)) ^ 0xffffffffU));
9697 }
9698
9699 /* 64 bit move 16 bit immediate negated.  */
9700 static void
9701 movn64 (sim_cpu *cpu, uint32_t val, uint32_t pos)
9702 {
9703   unsigned rd = INSTR (4, 0);
9704
9705   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9706   aarch64_set_reg_u64
9707     (cpu, rd, NO_SP, ((((uint64_t) val) << (pos * 16))
9708                       ^ 0xffffffffffffffffULL));
9709 }
9710
9711 /* 32 bit move 16 bit immediate keep remaining shorts.  */
9712 static void
9713 movk32 (sim_cpu *cpu, uint32_t val, uint32_t pos)
9714 {
9715   unsigned rd = INSTR (4, 0);
9716   uint32_t current = aarch64_get_reg_u32 (cpu, rd, NO_SP);
9717   uint32_t value = val << (pos * 16);
9718   uint32_t mask = ~(0xffffU << (pos * 16));
9719
9720   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9721   aarch64_set_reg_u64 (cpu, rd, NO_SP, (value | (current & mask)));
9722 }
9723
9724 /* 64 bit move 16 it immediate keep remaining shorts.  */
9725 static void
9726 movk64 (sim_cpu *cpu, uint32_t val, uint32_t pos)
9727 {
9728   unsigned rd = INSTR (4, 0);
9729   uint64_t current = aarch64_get_reg_u64 (cpu, rd, NO_SP);
9730   uint64_t value = (uint64_t) val << (pos * 16);
9731   uint64_t mask = ~(0xffffULL << (pos * 16));
9732
9733   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9734   aarch64_set_reg_u64 (cpu, rd, NO_SP, (value | (current & mask)));
9735 }
9736
9737 static void
9738 dexMoveWideImmediate (sim_cpu *cpu)
9739 {
9740   /* assert instr[28:23] = 100101
9741      instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
9742      instr[30,29] = op : 0 ==> MOVN, 1 ==> UNALLOC, 2 ==> MOVZ, 3 ==> MOVK
9743      instr[22,21] = shift : 00 == LSL#0, 01 = LSL#16, 10 = LSL#32, 11 = LSL#48
9744      instr[20,5] = uimm16
9745      instr[4,0] = Rd  */
9746
9747   /* N.B. the (multiple of 16) shift is applied by the called routine,
9748      we just pass the multiplier.  */
9749
9750   uint32_t imm;
9751   uint32_t size = INSTR (31, 31);
9752   uint32_t op = INSTR (30, 29);
9753   uint32_t shift = INSTR (22, 21);
9754
9755   /* 32 bit can only shift 0 or 1 lot of 16.
9756      anything else is an unallocated instruction.  */
9757   if (size == 0 && (shift > 1))
9758     HALT_UNALLOC;
9759
9760   if (op == 1)
9761     HALT_UNALLOC;
9762
9763   imm = INSTR (20, 5);
9764
9765   if (size == 0)
9766     {
9767       if (op == 0)
9768         movn32 (cpu, imm, shift);
9769       else if (op == 2)
9770         movz32 (cpu, imm, shift);
9771       else
9772         movk32 (cpu, imm, shift);
9773     }
9774   else
9775     {
9776       if (op == 0)
9777         movn64 (cpu, imm, shift);
9778       else if (op == 2)
9779         movz64 (cpu, imm, shift);
9780       else
9781         movk64 (cpu, imm, shift);
9782     }
9783 }
9784
9785 /* Bitfield operations.
9786    These take a pair of bit positions r and s which are in {0..31}
9787    or {0..63} depending on the instruction word size.
9788    N.B register args may not be SP.  */
9789
9790 /* OK, we start with ubfm which just needs to pick
9791    some bits out of source zero the rest and write
9792    the result to dest.  Just need two logical shifts.  */
9793
9794 /* 32 bit bitfield move, left and right of affected zeroed
9795    if r <= s Wd<s-r:0> = Wn<s:r> else Wd<32+s-r,32-r> = Wn<s:0>.  */
9796 static void
9797 ubfm32 (sim_cpu *cpu, uint32_t r, uint32_t s)
9798 {
9799   unsigned rd;
9800   unsigned rn = INSTR (9, 5);
9801   uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
9802
9803   /* Pick either s+1-r or s+1 consecutive bits out of the original word.  */
9804   if (r <= s)
9805     {
9806       /* 31:...:s:xxx:r:...:0 ==> 31:...:s-r:xxx:0.
9807          We want only bits s:xxx:r at the bottom of the word
9808          so we LSL bit s up to bit 31 i.e. by 31 - s
9809          and then we LSR to bring bit 31 down to bit s - r
9810          i.e. by 31 + r - s.  */
9811       value <<= 31 - s;
9812       value >>= 31 + r - s;
9813     }
9814   else
9815     {
9816       /* 31:...:s:xxx:0 ==> 31:...:31-(r-1)+s:xxx:31-(r-1):...:0
9817          We want only bits s:xxx:0 starting at it 31-(r-1)
9818          so we LSL bit s up to bit 31 i.e. by 31 - s
9819          and then we LSL to bring bit 31 down to 31-(r-1)+s
9820          i.e. by r - (s + 1).  */
9821       value <<= 31 - s;
9822       value >>= r - (s + 1);
9823     }
9824
9825   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9826   rd = INSTR (4, 0);
9827   aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
9828 }
9829
9830 /* 64 bit bitfield move, left and right of affected zeroed
9831    if r <= s Wd<s-r:0> = Wn<s:r> else Wd<64+s-r,64-r> = Wn<s:0>.  */
9832 static void
9833 ubfm (sim_cpu *cpu, uint32_t r, uint32_t s)
9834 {
9835   unsigned rd;
9836   unsigned rn = INSTR (9, 5);
9837   uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
9838
9839   if (r <= s)
9840     {
9841       /* 63:...:s:xxx:r:...:0 ==> 63:...:s-r:xxx:0.
9842          We want only bits s:xxx:r at the bottom of the word.
9843          So we LSL bit s up to bit 63 i.e. by 63 - s
9844          and then we LSR to bring bit 63 down to bit s - r
9845          i.e. by 63 + r - s.  */
9846       value <<= 63 - s;
9847       value >>= 63 + r - s;
9848     }
9849   else
9850     {
9851       /* 63:...:s:xxx:0 ==> 63:...:63-(r-1)+s:xxx:63-(r-1):...:0.
9852          We want only bits s:xxx:0 starting at it 63-(r-1).
9853          So we LSL bit s up to bit 63 i.e. by 63 - s
9854          and then we LSL to bring bit 63 down to 63-(r-1)+s
9855          i.e. by r - (s + 1).  */
9856       value <<= 63 - s;
9857       value >>= r - (s + 1);
9858     }
9859
9860   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9861   rd = INSTR (4, 0);
9862   aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
9863 }
9864
9865 /* The signed versions need to insert sign bits
9866    on the left of the inserted bit field. so we do
9867    much the same as the unsigned version except we
9868    use an arithmetic shift right -- this just means
9869    we need to operate on signed values.  */
9870
9871 /* 32 bit bitfield move, left of affected sign-extended, right zeroed.  */
9872 /* If r <= s Wd<s-r:0> = Wn<s:r> else Wd<32+s-r,32-r> = Wn<s:0>.  */
9873 static void
9874 sbfm32 (sim_cpu *cpu, uint32_t r, uint32_t s)
9875 {
9876   unsigned rd;
9877   unsigned rn = INSTR (9, 5);
9878   /* as per ubfm32 but use an ASR instead of an LSR.  */
9879   int32_t value = aarch64_get_reg_s32 (cpu, rn, NO_SP);
9880
9881   if (r <= s)
9882     {
9883       value <<= 31 - s;
9884       value >>= 31 + r - s;
9885     }
9886   else
9887     {
9888       value <<= 31 - s;
9889       value >>= r - (s + 1);
9890     }
9891
9892   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9893   rd = INSTR (4, 0);
9894   aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) value);
9895 }
9896
9897 /* 64 bit bitfield move, left of affected sign-extended, right zeroed.  */
9898 /* If r <= s Wd<s-r:0> = Wn<s:r> else Wd<64+s-r,64-r> = Wn<s:0>.  */
9899 static void
9900 sbfm (sim_cpu *cpu, uint32_t r, uint32_t s)
9901 {
9902   unsigned rd;
9903   unsigned rn = INSTR (9, 5);
9904   /* acpu per ubfm but use an ASR instead of an LSR.  */
9905   int64_t value = aarch64_get_reg_s64 (cpu, rn, NO_SP);
9906
9907   if (r <= s)
9908     {
9909       value <<= 63 - s;
9910       value >>= 63 + r - s;
9911     }
9912   else
9913     {
9914       value <<= 63 - s;
9915       value >>= r - (s + 1);
9916     }
9917
9918   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9919   rd = INSTR (4, 0);
9920   aarch64_set_reg_s64 (cpu, rd, NO_SP, value);
9921 }
9922
9923 /* Finally, these versions leave non-affected bits
9924    as is. so we need to generate the bits as per
9925    ubfm and also generate a mask to pick the
9926    bits from the original and computed values.  */
9927
9928 /* 32 bit bitfield move, non-affected bits left as is.
9929    If r <= s Wd<s-r:0> = Wn<s:r> else Wd<32+s-r,32-r> = Wn<s:0>.  */
9930 static void
9931 bfm32 (sim_cpu *cpu, uint32_t r, uint32_t s)
9932 {
9933   unsigned rn = INSTR (9, 5);
9934   uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
9935   uint32_t mask = -1;
9936   unsigned rd;
9937   uint32_t value2;
9938
9939   /* Pick either s+1-r or s+1 consecutive bits out of the original word.  */
9940   if (r <= s)
9941     {
9942       /* 31:...:s:xxx:r:...:0 ==> 31:...:s-r:xxx:0.
9943          We want only bits s:xxx:r at the bottom of the word
9944          so we LSL bit s up to bit 31 i.e. by 31 - s
9945          and then we LSR to bring bit 31 down to bit s - r
9946          i.e. by 31 + r - s.  */
9947       value <<= 31 - s;
9948       value >>= 31 + r - s;
9949       /* the mask must include the same bits.  */
9950       mask <<= 31 - s;
9951       mask >>= 31 + r - s;
9952     }
9953   else
9954     {
9955       /* 31:...:s:xxx:0 ==> 31:...:31-(r-1)+s:xxx:31-(r-1):...:0.
9956          We want only bits s:xxx:0 starting at it 31-(r-1)
9957          so we LSL bit s up to bit 31 i.e. by 31 - s
9958          and then we LSL to bring bit 31 down to 31-(r-1)+s
9959          i.e. by r - (s + 1).  */
9960       value <<= 31 - s;
9961       value >>= r - (s + 1);
9962       /* The mask must include the same bits.  */
9963       mask <<= 31 - s;
9964       mask >>= r - (s + 1);
9965     }
9966
9967   rd = INSTR (4, 0);
9968   value2 = aarch64_get_reg_u32 (cpu, rd, NO_SP);
9969
9970   value2 &= ~mask;
9971   value2 |= value;
9972
9973   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
9974   aarch64_set_reg_u64
9975     (cpu, rd, NO_SP, (aarch64_get_reg_u32 (cpu, rd, NO_SP) & ~mask) | value);
9976 }
9977
9978 /* 64 bit bitfield move, non-affected bits left as is.
9979    If r <= s Wd<s-r:0> = Wn<s:r> else Wd<64+s-r,64-r> = Wn<s:0>.  */
9980 static void
9981 bfm (sim_cpu *cpu, uint32_t r, uint32_t s)
9982 {
9983   unsigned rd;
9984   unsigned rn = INSTR (9, 5);
9985   uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
9986   uint64_t mask = 0xffffffffffffffffULL;
9987
9988   if (r <= s)
9989     {
9990       /* 63:...:s:xxx:r:...:0 ==> 63:...:s-r:xxx:0.
9991          We want only bits s:xxx:r at the bottom of the word
9992          so we LSL bit s up to bit 63 i.e. by 63 - s
9993          and then we LSR to bring bit 63 down to bit s - r
9994          i.e. by 63 + r - s.  */
9995       value <<= 63 - s;
9996       value >>= 63 + r - s;
9997       /* The mask must include the same bits.  */
9998       mask <<= 63 - s;
9999       mask >>= 63 + r - s;
10000     }
10001   else
10002     {
10003       /* 63:...:s:xxx:0 ==> 63:...:63-(r-1)+s:xxx:63-(r-1):...:0
10004          We want only bits s:xxx:0 starting at it 63-(r-1)
10005          so we LSL bit s up to bit 63 i.e. by 63 - s
10006          and then we LSL to bring bit 63 down to 63-(r-1)+s
10007          i.e. by r - (s + 1).  */
10008       value <<= 63 - s;
10009       value >>= r - (s + 1);
10010       /* The mask must include the same bits.  */
10011       mask <<= 63 - s;
10012       mask >>= r - (s + 1);
10013     }
10014
10015   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
10016   rd = INSTR (4, 0);
10017   aarch64_set_reg_u64
10018     (cpu, rd, NO_SP, (aarch64_get_reg_u64 (cpu, rd, NO_SP) & ~mask) | value);
10019 }
10020
10021 static void
10022 dexBitfieldImmediate (sim_cpu *cpu)
10023 {
10024   /* assert instr[28:23] = 100110
10025      instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
10026      instr[30,29] = op : 0 ==> SBFM, 1 ==> BFM, 2 ==> UBFM, 3 ==> UNALLOC
10027      instr[22] = N : must be 0 for 32 bit, 1 for 64 bit ow UNALLOC
10028      instr[21,16] = immr : 0xxxxx for 32 bit, xxxxxx for 64 bit
10029      instr[15,10] = imms :  0xxxxx for 32 bit, xxxxxx for 64 bit
10030      instr[9,5] = Rn
10031      instr[4,0] = Rd  */
10032
10033   /* 32 bit operations must have N = 0 or else we have an UNALLOC.  */
10034   uint32_t dispatch;
10035   uint32_t imms;
10036   uint32_t size = INSTR (31, 31);
10037   uint32_t N = INSTR (22, 22);
10038   /* 32 bit operations must have immr[5] = 0 and imms[5] = 0.  */
10039   /* or else we have an UNALLOC.  */
10040   uint32_t immr = INSTR (21, 16);
10041
10042   if (~size & N)
10043     HALT_UNALLOC;
10044
10045   if (!size && uimm (immr, 5, 5))
10046     HALT_UNALLOC;
10047
10048   imms = INSTR (15, 10);
10049   if (!size && uimm (imms, 5, 5))
10050     HALT_UNALLOC;
10051
10052   /* Switch on combined size and op.  */
10053   dispatch = INSTR (31, 29);
10054   switch (dispatch)
10055     {
10056     case 0: sbfm32 (cpu, immr, imms); return;
10057     case 1: bfm32 (cpu, immr, imms); return;
10058     case 2: ubfm32 (cpu, immr, imms); return;
10059     case 4: sbfm (cpu, immr, imms); return;
10060     case 5: bfm (cpu, immr, imms); return;
10061     case 6: ubfm (cpu, immr, imms); return;
10062     default: HALT_UNALLOC;
10063     }
10064 }
10065
10066 static void
10067 do_EXTR_32 (sim_cpu *cpu)
10068 {
10069   /* instr[31:21] = 00010011100
10070      instr[20,16] = Rm
10071      instr[15,10] = imms :  0xxxxx for 32 bit
10072      instr[9,5]   = Rn
10073      instr[4,0]   = Rd  */
10074   unsigned rm   = INSTR (20, 16);
10075   unsigned imms = INSTR (15, 10) & 31;
10076   unsigned rn   = INSTR ( 9,  5);
10077   unsigned rd   = INSTR ( 4,  0);
10078   uint64_t val1;
10079   uint64_t val2;
10080
10081   val1 = aarch64_get_reg_u32 (cpu, rm, NO_SP);
10082   val1 >>= imms;
10083   val2 = aarch64_get_reg_u32 (cpu, rn, NO_SP);
10084   val2 <<= (32 - imms);
10085
10086   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
10087   aarch64_set_reg_u64 (cpu, rd, NO_SP, val1 | val2);
10088 }
10089
10090 static void
10091 do_EXTR_64 (sim_cpu *cpu)
10092 {
10093   /* instr[31:21] = 10010011100
10094      instr[20,16] = Rm
10095      instr[15,10] = imms
10096      instr[9,5]   = Rn
10097      instr[4,0]   = Rd  */
10098   unsigned rm   = INSTR (20, 16);
10099   unsigned imms = INSTR (15, 10) & 63;
10100   unsigned rn   = INSTR ( 9,  5);
10101   unsigned rd   = INSTR ( 4,  0);
10102   uint64_t val;
10103
10104   val = aarch64_get_reg_u64 (cpu, rm, NO_SP);
10105   val >>= imms;
10106   val |= (aarch64_get_reg_u64 (cpu, rn, NO_SP) << (64 - imms));
10107
10108   aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
10109 }
10110
10111 static void
10112 dexExtractImmediate (sim_cpu *cpu)
10113 {
10114   /* assert instr[28:23] = 100111
10115      instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
10116      instr[30,29] = op21 : 0 ==> EXTR, 1,2,3 ==> UNALLOC
10117      instr[22]    = N : must be 0 for 32 bit, 1 for 64 bit or UNALLOC
10118      instr[21]    = op0 : must be 0 or UNALLOC
10119      instr[20,16] = Rm
10120      instr[15,10] = imms :  0xxxxx for 32 bit, xxxxxx for 64 bit
10121      instr[9,5]   = Rn
10122      instr[4,0]   = Rd  */
10123
10124   /* 32 bit operations must have N = 0 or else we have an UNALLOC.  */
10125   /* 64 bit operations must have N = 1 or else we have an UNALLOC.  */
10126   uint32_t dispatch;
10127   uint32_t size = INSTR (31, 31);
10128   uint32_t N = INSTR (22, 22);
10129   /* 32 bit operations must have imms[5] = 0
10130      or else we have an UNALLOC.  */
10131   uint32_t imms = INSTR (15, 10);
10132
10133   if (size ^ N)
10134     HALT_UNALLOC;
10135
10136   if (!size && uimm (imms, 5, 5))
10137     HALT_UNALLOC;
10138
10139   /* Switch on combined size and op.  */
10140   dispatch = INSTR (31, 29);
10141
10142   if (dispatch == 0)
10143     do_EXTR_32 (cpu);
10144
10145   else if (dispatch == 4)
10146     do_EXTR_64 (cpu);
10147
10148   else if (dispatch == 1)
10149     HALT_NYI;
10150   else
10151     HALT_UNALLOC;
10152 }
10153
10154 static void
10155 dexDPImm (sim_cpu *cpu)
10156 {
10157   /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu));
10158      assert  group == GROUP_DPIMM_1000 || grpoup == GROUP_DPIMM_1001
10159      bits [25,23] of a DPImm are the secondary dispatch vector.  */
10160   uint32_t group2 = dispatchDPImm (aarch64_get_instr (cpu));
10161
10162   switch (group2)
10163     {
10164     case DPIMM_PCADR_000:
10165     case DPIMM_PCADR_001:
10166       dexPCRelAddressing (cpu);
10167       return;
10168
10169     case DPIMM_ADDSUB_010:
10170     case DPIMM_ADDSUB_011:
10171       dexAddSubtractImmediate (cpu);
10172       return;
10173
10174     case DPIMM_LOG_100:
10175       dexLogicalImmediate (cpu);
10176       return;
10177
10178     case DPIMM_MOV_101:
10179       dexMoveWideImmediate (cpu);
10180       return;
10181
10182     case DPIMM_BITF_110:
10183       dexBitfieldImmediate (cpu);
10184       return;
10185
10186     case DPIMM_EXTR_111:
10187       dexExtractImmediate (cpu);
10188       return;
10189
10190     default:
10191       /* Should never reach here.  */
10192       HALT_NYI;
10193     }
10194 }
10195
10196 static void
10197 dexLoadUnscaledImmediate (sim_cpu *cpu)
10198 {
10199   /* instr[29,24] == 111_00
10200      instr[21] == 0
10201      instr[11,10] == 00
10202      instr[31,30] = size
10203      instr[26] = V
10204      instr[23,22] = opc
10205      instr[20,12] = simm9
10206      instr[9,5] = rn may be SP.  */
10207   /* unsigned rt = INSTR (4, 0);  */
10208   uint32_t V = INSTR (26, 26);
10209   uint32_t dispatch = ((INSTR (31, 30) << 2) | INSTR (23, 22));
10210   int32_t imm = simm32 (aarch64_get_instr (cpu), 20, 12);
10211
10212   if (!V)
10213     {
10214       /* GReg operations.  */
10215       switch (dispatch)
10216         {
10217         case 0:  sturb (cpu, imm); return;
10218         case 1:  ldurb32 (cpu, imm); return;
10219         case 2:  ldursb64 (cpu, imm); return;
10220         case 3:  ldursb32 (cpu, imm); return;
10221         case 4:  sturh (cpu, imm); return;
10222         case 5:  ldurh32 (cpu, imm); return;
10223         case 6:  ldursh64 (cpu, imm); return;
10224         case 7:  ldursh32 (cpu, imm); return;
10225         case 8:  stur32 (cpu, imm); return;
10226         case 9:  ldur32 (cpu, imm); return;
10227         case 10: ldursw (cpu, imm); return;
10228         case 12: stur64 (cpu, imm); return;
10229         case 13: ldur64 (cpu, imm); return;
10230
10231         case 14:
10232           /* PRFUM NYI.  */
10233           HALT_NYI;
10234
10235         default:
10236         case 11:
10237         case 15:
10238           HALT_UNALLOC;
10239         }
10240     }
10241
10242   /* FReg operations.  */
10243   switch (dispatch)
10244     {
10245     case 2:  fsturq (cpu, imm); return;
10246     case 3:  fldurq (cpu, imm); return;
10247     case 8:  fsturs (cpu, imm); return;
10248     case 9:  fldurs (cpu, imm); return;
10249     case 12: fsturd (cpu, imm); return;
10250     case 13: fldurd (cpu, imm); return;
10251
10252     case 0: /* STUR 8 bit FP.  */
10253     case 1: /* LDUR 8 bit FP.  */
10254     case 4: /* STUR 16 bit FP.  */
10255     case 5: /* LDUR 8 bit FP.  */
10256       HALT_NYI;
10257
10258     default:
10259     case 6:
10260     case 7:
10261     case 10:
10262     case 11:
10263     case 14:
10264     case 15:
10265       HALT_UNALLOC;
10266     }
10267 }
10268
10269 /*  N.B. A preliminary note regarding all the ldrs<x>32
10270     instructions
10271
10272    The signed value loaded by these instructions is cast to unsigned
10273    before being assigned to aarch64_get_reg_u64 (cpu, N) i.e. to the
10274    64 bit element of the GReg union. this performs a 32 bit sign extension
10275    (as required) but avoids 64 bit sign extension, thus ensuring that the
10276    top half of the register word is zero. this is what the spec demands
10277    when a 32 bit load occurs.  */
10278
10279 /* 32 bit load sign-extended byte scaled unsigned 12 bit.  */
10280 static void
10281 ldrsb32_abs (sim_cpu *cpu, uint32_t offset)
10282 {
10283   unsigned int rn = INSTR (9, 5);
10284   unsigned int rt = INSTR (4, 0);
10285
10286   /* The target register may not be SP but the source may be
10287      there is no scaling required for a byte load.  */
10288   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset;
10289   aarch64_set_reg_u64 (cpu, rt, NO_SP,
10290                        (int64_t) aarch64_get_mem_s8 (cpu, address));
10291 }
10292
10293 /* 32 bit load sign-extended byte scaled or unscaled zero-
10294    or sign-extended 32-bit register offset.  */
10295 static void
10296 ldrsb32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
10297 {
10298   unsigned int rm = INSTR (20, 16);
10299   unsigned int rn = INSTR (9, 5);
10300   unsigned int rt = INSTR (4, 0);
10301
10302   /* rn may reference SP, rm and rt must reference ZR.  */
10303
10304   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10305   int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
10306                                  extension);
10307
10308   /* There is no scaling required for a byte load.  */
10309   aarch64_set_reg_u64
10310     (cpu, rt, NO_SP, (int64_t) aarch64_get_mem_s8 (cpu, address
10311                                                    + displacement));
10312 }
10313
10314 /* 32 bit load sign-extended byte unscaled signed 9 bit with
10315    pre- or post-writeback.  */
10316 static void
10317 ldrsb32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
10318 {
10319   uint64_t address;
10320   unsigned int rn = INSTR (9, 5);
10321   unsigned int rt = INSTR (4, 0);
10322
10323   if (rn == rt && wb != NoWriteBack)
10324     HALT_UNALLOC;
10325
10326   address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10327
10328   if (wb == Pre)
10329       address += offset;
10330
10331   aarch64_set_reg_u64 (cpu, rt, NO_SP,
10332                        (int64_t) aarch64_get_mem_s8 (cpu, address));
10333
10334   if (wb == Post)
10335     address += offset;
10336
10337   if (wb != NoWriteBack)
10338     aarch64_set_reg_u64 (cpu, rn, NO_SP, address);
10339 }
10340
10341 /* 8 bit store scaled.  */
10342 static void
10343 fstrb_abs (sim_cpu *cpu, uint32_t offset)
10344 {
10345   unsigned st = INSTR (4, 0);
10346   unsigned rn = INSTR (9, 5);
10347
10348   aarch64_set_mem_u8 (cpu,
10349                       aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset,
10350                       aarch64_get_vec_u8 (cpu, st, 0));
10351 }
10352
10353 /* 8 bit store scaled or unscaled zero- or
10354    sign-extended 8-bit register offset.  */
10355 static void
10356 fstrb_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
10357 {
10358   unsigned rm = INSTR (20, 16);
10359   unsigned rn = INSTR (9, 5);
10360   unsigned st = INSTR (4, 0);
10361
10362   uint64_t  address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10363   int64_t   extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
10364                                extension);
10365   uint64_t  displacement = scaling == Scaled ? extended : 0;
10366
10367   aarch64_set_mem_u8
10368     (cpu, address + displacement, aarch64_get_vec_u8 (cpu, st, 0));
10369 }
10370
10371 /* 16 bit store scaled.  */
10372 static void
10373 fstrh_abs (sim_cpu *cpu, uint32_t offset)
10374 {
10375   unsigned st = INSTR (4, 0);
10376   unsigned rn = INSTR (9, 5);
10377
10378   aarch64_set_mem_u16
10379     (cpu,
10380      aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 16),
10381      aarch64_get_vec_u16 (cpu, st, 0));
10382 }
10383
10384 /* 16 bit store scaled or unscaled zero-
10385    or sign-extended 16-bit register offset.  */
10386 static void
10387 fstrh_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
10388 {
10389   unsigned rm = INSTR (20, 16);
10390   unsigned rn = INSTR (9, 5);
10391   unsigned st = INSTR (4, 0);
10392
10393   uint64_t  address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10394   int64_t   extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
10395                                extension);
10396   uint64_t  displacement = OPT_SCALE (extended, 16, scaling);
10397
10398   aarch64_set_mem_u16
10399     (cpu, address + displacement, aarch64_get_vec_u16 (cpu, st, 0));
10400 }
10401
10402 /* 32 bit store scaled unsigned 12 bit.  */
10403 static void
10404 fstrs_abs (sim_cpu *cpu, uint32_t offset)
10405 {
10406   unsigned st = INSTR (4, 0);
10407   unsigned rn = INSTR (9, 5);
10408
10409   aarch64_set_mem_u32
10410     (cpu,
10411      aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 32),
10412      aarch64_get_vec_u32 (cpu, st, 0));
10413 }
10414
10415 /* 32 bit store unscaled signed 9 bit with pre- or post-writeback.  */
10416 static void
10417 fstrs_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
10418 {
10419   unsigned rn = INSTR (9, 5);
10420   unsigned st = INSTR (4, 0);
10421
10422   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10423
10424   if (wb != Post)
10425     address += offset;
10426
10427   aarch64_set_mem_u32 (cpu, address, aarch64_get_vec_u32 (cpu, st, 0));
10428
10429   if (wb == Post)
10430     address += offset;
10431
10432   if (wb != NoWriteBack)
10433     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
10434 }
10435
10436 /* 32 bit store scaled or unscaled zero-
10437    or sign-extended 32-bit register offset.  */
10438 static void
10439 fstrs_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
10440 {
10441   unsigned rm = INSTR (20, 16);
10442   unsigned rn = INSTR (9, 5);
10443   unsigned st = INSTR (4, 0);
10444
10445   uint64_t  address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10446   int64_t   extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
10447                                extension);
10448   uint64_t  displacement = OPT_SCALE (extended, 32, scaling);
10449
10450   aarch64_set_mem_u32
10451     (cpu, address + displacement, aarch64_get_vec_u32 (cpu, st, 0));
10452 }
10453
10454 /* 64 bit store scaled unsigned 12 bit.  */
10455 static void
10456 fstrd_abs (sim_cpu *cpu, uint32_t offset)
10457 {
10458   unsigned st = INSTR (4, 0);
10459   unsigned rn = INSTR (9, 5);
10460
10461   aarch64_set_mem_u64
10462     (cpu,
10463      aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 64),
10464      aarch64_get_vec_u64 (cpu, st, 0));
10465 }
10466
10467 /* 64 bit store unscaled signed 9 bit with pre- or post-writeback.  */
10468 static void
10469 fstrd_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
10470 {
10471   unsigned rn = INSTR (9, 5);
10472   unsigned st = INSTR (4, 0);
10473
10474   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10475
10476   if (wb != Post)
10477     address += offset;
10478
10479   aarch64_set_mem_u64 (cpu, address, aarch64_get_vec_u64 (cpu, st, 0));
10480
10481   if (wb == Post)
10482     address += offset;
10483
10484   if (wb != NoWriteBack)
10485     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
10486 }
10487
10488 /* 64 bit store scaled or unscaled zero-
10489    or sign-extended 32-bit register offset.  */
10490 static void
10491 fstrd_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
10492 {
10493   unsigned rm = INSTR (20, 16);
10494   unsigned rn = INSTR (9, 5);
10495   unsigned st = INSTR (4, 0);
10496
10497   uint64_t  address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10498   int64_t   extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
10499                                extension);
10500   uint64_t  displacement = OPT_SCALE (extended, 64, scaling);
10501
10502   aarch64_set_mem_u64
10503     (cpu, address + displacement, aarch64_get_vec_u64 (cpu, st, 0));
10504 }
10505
10506 /* 128 bit store scaled unsigned 12 bit.  */
10507 static void
10508 fstrq_abs (sim_cpu *cpu, uint32_t offset)
10509 {
10510   FRegister a;
10511   unsigned st = INSTR (4, 0);
10512   unsigned rn = INSTR (9, 5);
10513   uint64_t addr;
10514
10515   aarch64_get_FP_long_double (cpu, st, & a);
10516
10517   addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 128);
10518   aarch64_set_mem_long_double (cpu, addr, a);
10519 }
10520
10521 /* 128 bit store unscaled signed 9 bit with pre- or post-writeback.  */
10522 static void
10523 fstrq_wb (sim_cpu *cpu, int32_t offset, WriteBack wb)
10524 {
10525   FRegister a;
10526   unsigned rn = INSTR (9, 5);
10527   unsigned st = INSTR (4, 0);
10528   uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10529
10530   if (wb != Post)
10531     address += offset;
10532
10533   aarch64_get_FP_long_double (cpu, st, & a);
10534   aarch64_set_mem_long_double (cpu, address, a);
10535
10536   if (wb == Post)
10537     address += offset;
10538
10539   if (wb != NoWriteBack)
10540     aarch64_set_reg_u64 (cpu, rn, SP_OK, address);
10541 }
10542
10543 /* 128 bit store scaled or unscaled zero-
10544    or sign-extended 32-bit register offset.  */
10545 static void
10546 fstrq_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension)
10547 {
10548   unsigned rm = INSTR (20, 16);
10549   unsigned rn = INSTR (9, 5);
10550   unsigned st = INSTR (4, 0);
10551
10552   uint64_t  address = aarch64_get_reg_u64 (cpu, rn, SP_OK);
10553   int64_t   extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP),
10554                                extension);
10555   uint64_t  displacement = OPT_SCALE (extended, 128, scaling);
10556
10557   FRegister a;
10558
10559   aarch64_get_FP_long_double (cpu, st, & a);
10560   aarch64_set_mem_long_double (cpu, address + displacement, a);
10561 }
10562
10563 static void
10564 dexLoadImmediatePrePost (sim_cpu *cpu)
10565 {
10566   /* instr[31,30] = size
10567      instr[29,27] = 111
10568      instr[26]    = V
10569      instr[25,24] = 00
10570      instr[23,22] = opc
10571      instr[21]    = 0
10572      instr[20,12] = simm9
10573      instr[11]    = wb : 0 ==> Post, 1 ==> Pre
10574      instr[10]    = 0
10575      instr[9,5]   = Rn may be SP.
10576      instr[4,0]   = Rt */
10577
10578   uint32_t  V        = INSTR (26, 26);
10579   uint32_t  dispatch = ((INSTR (31, 30) << 2) | INSTR (23, 22));
10580   int32_t   imm      = simm32 (aarch64_get_instr (cpu), 20, 12);
10581   WriteBack wb       = INSTR (11, 11);
10582
10583   if (!V)
10584     {
10585       /* GReg operations.  */
10586       switch (dispatch)
10587         {
10588         case 0:  strb_wb (cpu, imm, wb); return;
10589         case 1:  ldrb32_wb (cpu, imm, wb); return;
10590         case 2:  ldrsb_wb (cpu, imm, wb); return;
10591         case 3:  ldrsb32_wb (cpu, imm, wb); return;
10592         case 4:  strh_wb (cpu, imm, wb); return;
10593         case 5:  ldrh32_wb (cpu, imm, wb); return;
10594         case 6:  ldrsh64_wb (cpu, imm, wb); return;
10595         case 7:  ldrsh32_wb (cpu, imm, wb); return;
10596         case 8:  str32_wb (cpu, imm, wb); return;
10597         case 9:  ldr32_wb (cpu, imm, wb); return;
10598         case 10: ldrsw_wb (cpu, imm, wb); return;
10599         case 12: str_wb (cpu, imm, wb); return;
10600         case 13: ldr_wb (cpu, imm, wb); return;
10601
10602         default:
10603         case 11:
10604         case 14:
10605         case 15:
10606           HALT_UNALLOC;
10607         }
10608     }
10609
10610   /* FReg operations.  */
10611   switch (dispatch)
10612     {
10613     case 2:  fstrq_wb (cpu, imm, wb); return;
10614     case 3:  fldrq_wb (cpu, imm, wb); return;
10615     case 8:  fstrs_wb (cpu, imm, wb); return;
10616     case 9:  fldrs_wb (cpu, imm, wb); return;
10617     case 12: fstrd_wb (cpu, imm, wb); return;
10618     case 13: fldrd_wb (cpu, imm, wb); return;
10619
10620     case 0:       /* STUR 8 bit FP.  */
10621     case 1:       /* LDUR 8 bit FP.  */
10622     case 4:       /* STUR 16 bit FP.  */
10623     case 5:       /* LDUR 8 bit FP.  */
10624       HALT_NYI;
10625
10626     default:
10627     case 6:
10628     case 7:
10629     case 10:
10630     case 11:
10631     case 14:
10632     case 15:
10633       HALT_UNALLOC;
10634     }
10635 }
10636
10637 static void
10638 dexLoadRegisterOffset (sim_cpu *cpu)
10639 {
10640   /* instr[31,30] = size
10641      instr[29,27] = 111
10642      instr[26]    = V
10643      instr[25,24] = 00
10644      instr[23,22] = opc
10645      instr[21]    = 1
10646      instr[20,16] = rm
10647      instr[15,13] = option : 010 ==> UXTW, 011 ==> UXTX/LSL,
10648                              110 ==> SXTW, 111 ==> SXTX,
10649                              ow ==> RESERVED
10650      instr[12]    = scaled
10651      instr[11,10] = 10
10652      instr[9,5]   = rn
10653      instr[4,0]   = rt.  */
10654
10655   uint32_t  V = INSTR (26, 26);
10656   uint32_t  dispatch = ((INSTR (31, 30) << 2) | INSTR (23, 22));
10657   Scaling   scale = INSTR (12, 12);
10658   Extension extensionType = INSTR (15, 13);
10659
10660   /* Check for illegal extension types.  */
10661   if (uimm (extensionType, 1, 1) == 0)
10662     HALT_UNALLOC;
10663
10664   if (extensionType == UXTX || extensionType == SXTX)
10665     extensionType = NoExtension;
10666
10667   if (!V)
10668     {
10669       /* GReg operations.  */
10670       switch (dispatch)
10671         {
10672         case 0:  strb_scale_ext (cpu, scale, extensionType); return;
10673         case 1:  ldrb32_scale_ext (cpu, scale, extensionType); return;
10674         case 2:  ldrsb_scale_ext (cpu, scale, extensionType); return;
10675         case 3:  ldrsb32_scale_ext (cpu, scale, extensionType); return;
10676         case 4:  strh_scale_ext (cpu, scale, extensionType); return;
10677         case 5:  ldrh32_scale_ext (cpu, scale, extensionType); return;
10678         case 6:  ldrsh_scale_ext (cpu, scale, extensionType); return;
10679         case 7:  ldrsh32_scale_ext (cpu, scale, extensionType); return;
10680         case 8:  str32_scale_ext (cpu, scale, extensionType); return;
10681         case 9:  ldr32_scale_ext (cpu, scale, extensionType); return;
10682         case 10: ldrsw_scale_ext (cpu, scale, extensionType); return;
10683         case 12: str_scale_ext (cpu, scale, extensionType); return;
10684         case 13: ldr_scale_ext (cpu, scale, extensionType); return;
10685         case 14: prfm_scale_ext (cpu, scale, extensionType); return;
10686
10687         default:
10688         case 11:
10689         case 15:
10690           HALT_UNALLOC;
10691         }
10692     }
10693
10694   /* FReg operations.  */
10695   switch (dispatch)
10696     {
10697     case 1: /* LDUR 8 bit FP.  */
10698       HALT_NYI;
10699     case 3:  fldrq_scale_ext (cpu, scale, extensionType); return;
10700     case 5: /* LDUR 8 bit FP.  */
10701       HALT_NYI;
10702     case 9:  fldrs_scale_ext (cpu, scale, extensionType); return;
10703     case 13: fldrd_scale_ext (cpu, scale, extensionType); return;
10704
10705     case 0:  fstrb_scale_ext (cpu, scale, extensionType); return;
10706     case 2:  fstrq_scale_ext (cpu, scale, extensionType); return;
10707     case 4:  fstrh_scale_ext (cpu, scale, extensionType); return;
10708     case 8:  fstrs_scale_ext (cpu, scale, extensionType); return;
10709     case 12: fstrd_scale_ext (cpu, scale, extensionType); return;
10710
10711     default:
10712     case 6:
10713     case 7:
10714     case 10:
10715     case 11:
10716     case 14:
10717     case 15:
10718       HALT_UNALLOC;
10719     }
10720 }
10721
10722 static void
10723 dexLoadUnsignedImmediate (sim_cpu *cpu)
10724 {
10725   /* instr[29,24] == 111_01
10726      instr[31,30] = size
10727      instr[26]    = V
10728      instr[23,22] = opc
10729      instr[21,10] = uimm12 : unsigned immediate offset
10730      instr[9,5]   = rn may be SP.
10731      instr[4,0]   = rt.  */
10732
10733   uint32_t V = INSTR (26,26);
10734   uint32_t dispatch = ((INSTR (31, 30) << 2) | INSTR (23, 22));
10735   uint32_t imm = INSTR (21, 10);
10736
10737   if (!V)
10738     {
10739       /* GReg operations.  */
10740       switch (dispatch)
10741         {
10742         case 0:  strb_abs (cpu, imm); return;
10743         case 1:  ldrb32_abs (cpu, imm); return;
10744         case 2:  ldrsb_abs (cpu, imm); return;
10745         case 3:  ldrsb32_abs (cpu, imm); return;
10746         case 4:  strh_abs (cpu, imm); return;
10747         case 5:  ldrh32_abs (cpu, imm); return;
10748         case 6:  ldrsh_abs (cpu, imm); return;
10749         case 7:  ldrsh32_abs (cpu, imm); return;
10750         case 8:  str32_abs (cpu, imm); return;
10751         case 9:  ldr32_abs (cpu, imm); return;
10752         case 10: ldrsw_abs (cpu, imm); return;
10753         case 12: str_abs (cpu, imm); return;
10754         case 13: ldr_abs (cpu, imm); return;
10755         case 14: prfm_abs (cpu, imm); return;
10756
10757         default:
10758         case 11:
10759         case 15:
10760           HALT_UNALLOC;
10761         }
10762     }
10763
10764   /* FReg operations.  */
10765   switch (dispatch)
10766     {
10767     case 0:  fstrb_abs (cpu, imm); return;
10768     case 4:  fstrh_abs (cpu, imm); return;
10769     case 8:  fstrs_abs (cpu, imm); return;
10770     case 12: fstrd_abs (cpu, imm); return;
10771     case 2:  fstrq_abs (cpu, imm); return;
10772
10773     case 1:  fldrb_abs (cpu, imm); return;
10774     case 5:  fldrh_abs (cpu, imm); return;
10775     case 9:  fldrs_abs (cpu, imm); return;
10776     case 13: fldrd_abs (cpu, imm); return;
10777     case 3:  fldrq_abs (cpu, imm); return;
10778
10779     default:
10780     case 6:
10781     case 7:
10782     case 10:
10783     case 11:
10784     case 14:
10785     case 15:
10786       HALT_UNALLOC;
10787     }
10788 }
10789
10790 static void
10791 dexLoadExclusive (sim_cpu *cpu)
10792 {
10793   /* assert instr[29:24] = 001000;
10794      instr[31,30] = size
10795      instr[23] = 0 if exclusive
10796      instr[22] = L : 1 if load, 0 if store
10797      instr[21] = 1 if pair
10798      instr[20,16] = Rs
10799      instr[15] = o0 : 1 if ordered
10800      instr[14,10] = Rt2
10801      instr[9,5] = Rn
10802      instr[4.0] = Rt.  */
10803
10804   switch (INSTR (22, 21))
10805     {
10806     case 2:   ldxr (cpu); return;
10807     case 0:   stxr (cpu); return;
10808     default:  HALT_NYI;
10809     }
10810 }
10811
10812 static void
10813 dexLoadOther (sim_cpu *cpu)
10814 {
10815   uint32_t dispatch;
10816
10817   /* instr[29,25] = 111_0
10818      instr[24] == 0 ==> dispatch, 1 ==> ldst reg unsigned immediate
10819      instr[21:11,10] is the secondary dispatch.  */
10820   if (INSTR (24, 24))
10821     {
10822       dexLoadUnsignedImmediate (cpu);
10823       return;
10824     }
10825
10826   dispatch = ((INSTR (21, 21) << 2) | INSTR (11, 10));
10827   switch (dispatch)
10828     {
10829     case 0: dexLoadUnscaledImmediate (cpu); return;
10830     case 1: dexLoadImmediatePrePost (cpu); return;
10831     case 3: dexLoadImmediatePrePost (cpu); return;
10832     case 6: dexLoadRegisterOffset (cpu); return;
10833
10834     default:
10835     case 2:
10836     case 4:
10837     case 5:
10838     case 7:
10839       HALT_NYI;
10840     }
10841 }
10842
10843 static void
10844 store_pair_u32 (sim_cpu *cpu, int32_t offset, WriteBack wb)
10845 {
10846   unsigned rn = INSTR (14, 10);
10847   unsigned rd = INSTR (9, 5);
10848   unsigned rm = INSTR (4, 0);
10849   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
10850
10851   if ((rn == rd || rm == rd) && wb != NoWriteBack)
10852     HALT_UNALLOC; /* ??? */
10853
10854   offset <<= 2;
10855
10856   if (wb != Post)
10857     address += offset;
10858
10859   aarch64_set_mem_u32 (cpu, address,
10860                        aarch64_get_reg_u32 (cpu, rm, NO_SP));
10861   aarch64_set_mem_u32 (cpu, address + 4,
10862                        aarch64_get_reg_u32 (cpu, rn, NO_SP));
10863
10864   if (wb == Post)
10865     address += offset;
10866
10867   if (wb != NoWriteBack)
10868     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
10869 }
10870
10871 static void
10872 store_pair_u64 (sim_cpu *cpu, int32_t offset, WriteBack wb)
10873 {
10874   unsigned rn = INSTR (14, 10);
10875   unsigned rd = INSTR (9, 5);
10876   unsigned rm = INSTR (4, 0);
10877   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
10878
10879   if ((rn == rd || rm == rd) && wb != NoWriteBack)
10880     HALT_UNALLOC; /* ??? */
10881
10882   offset <<= 3;
10883
10884   if (wb != Post)
10885     address += offset;
10886
10887   aarch64_set_mem_u64 (cpu, address,
10888                        aarch64_get_reg_u64 (cpu, rm, NO_SP));
10889   aarch64_set_mem_u64 (cpu, address + 8,
10890                        aarch64_get_reg_u64 (cpu, rn, NO_SP));
10891
10892   if (wb == Post)
10893     address += offset;
10894
10895   if (wb != NoWriteBack)
10896     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
10897 }
10898
10899 static void
10900 load_pair_u32 (sim_cpu *cpu, int32_t offset, WriteBack wb)
10901 {
10902   unsigned rn = INSTR (14, 10);
10903   unsigned rd = INSTR (9, 5);
10904   unsigned rm = INSTR (4, 0);
10905   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
10906
10907   /* Treat this as unalloc to make sure we don't do it.  */
10908   if (rn == rm)
10909     HALT_UNALLOC;
10910
10911   offset <<= 2;
10912
10913   if (wb != Post)
10914     address += offset;
10915
10916   aarch64_set_reg_u64 (cpu, rm, SP_OK, aarch64_get_mem_u32 (cpu, address));
10917   aarch64_set_reg_u64 (cpu, rn, SP_OK, aarch64_get_mem_u32 (cpu, address + 4));
10918
10919   if (wb == Post)
10920     address += offset;
10921
10922   if (wb != NoWriteBack)
10923     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
10924 }
10925
10926 static void
10927 load_pair_s32 (sim_cpu *cpu, int32_t offset, WriteBack wb)
10928 {
10929   unsigned rn = INSTR (14, 10);
10930   unsigned rd = INSTR (9, 5);
10931   unsigned rm = INSTR (4, 0);
10932   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
10933
10934   /* Treat this as unalloc to make sure we don't do it.  */
10935   if (rn == rm)
10936     HALT_UNALLOC;
10937
10938   offset <<= 2;
10939
10940   if (wb != Post)
10941     address += offset;
10942
10943   aarch64_set_reg_s64 (cpu, rm, SP_OK, aarch64_get_mem_s32 (cpu, address));
10944   aarch64_set_reg_s64 (cpu, rn, SP_OK, aarch64_get_mem_s32 (cpu, address + 4));
10945
10946   if (wb == Post)
10947     address += offset;
10948
10949   if (wb != NoWriteBack)
10950     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
10951 }
10952
10953 static void
10954 load_pair_u64 (sim_cpu *cpu, int32_t offset, WriteBack wb)
10955 {
10956   unsigned rn = INSTR (14, 10);
10957   unsigned rd = INSTR (9, 5);
10958   unsigned rm = INSTR (4, 0);
10959   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
10960
10961   /* Treat this as unalloc to make sure we don't do it.  */
10962   if (rn == rm)
10963     HALT_UNALLOC;
10964
10965   offset <<= 3;
10966
10967   if (wb != Post)
10968     address += offset;
10969
10970   aarch64_set_reg_u64 (cpu, rm, SP_OK, aarch64_get_mem_u64 (cpu, address));
10971   aarch64_set_reg_u64 (cpu, rn, SP_OK, aarch64_get_mem_u64 (cpu, address + 8));
10972
10973   if (wb == Post)
10974     address += offset;
10975
10976   if (wb != NoWriteBack)
10977     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
10978 }
10979
10980 static void
10981 dex_load_store_pair_gr (sim_cpu *cpu)
10982 {
10983   /* instr[31,30] = size (10=> 64-bit, 01=> signed 32-bit, 00=> 32-bit)
10984      instr[29,25] = instruction encoding: 101_0
10985      instr[26]    = V : 1 if fp 0 if gp
10986      instr[24,23] = addressing mode (10=> offset, 01=> post, 11=> pre)
10987      instr[22]    = load/store (1=> load)
10988      instr[21,15] = signed, scaled, offset
10989      instr[14,10] = Rn
10990      instr[ 9, 5] = Rd
10991      instr[ 4, 0] = Rm.  */
10992
10993   uint32_t dispatch = ((INSTR (31, 30) << 3) | INSTR (24, 22));
10994   int32_t offset = simm32 (aarch64_get_instr (cpu), 21, 15);
10995
10996   switch (dispatch)
10997     {
10998     case 2: store_pair_u32 (cpu, offset, Post); return;
10999     case 3: load_pair_u32  (cpu, offset, Post); return;
11000     case 4: store_pair_u32 (cpu, offset, NoWriteBack); return;
11001     case 5: load_pair_u32  (cpu, offset, NoWriteBack); return;
11002     case 6: store_pair_u32 (cpu, offset, Pre); return;
11003     case 7: load_pair_u32  (cpu, offset, Pre); return;
11004
11005     case 11: load_pair_s32  (cpu, offset, Post); return;
11006     case 13: load_pair_s32  (cpu, offset, NoWriteBack); return;
11007     case 15: load_pair_s32  (cpu, offset, Pre); return;
11008
11009     case 18: store_pair_u64 (cpu, offset, Post); return;
11010     case 19: load_pair_u64  (cpu, offset, Post); return;
11011     case 20: store_pair_u64 (cpu, offset, NoWriteBack); return;
11012     case 21: load_pair_u64  (cpu, offset, NoWriteBack); return;
11013     case 22: store_pair_u64 (cpu, offset, Pre); return;
11014     case 23: load_pair_u64  (cpu, offset, Pre); return;
11015
11016     default:
11017       HALT_UNALLOC;
11018     }
11019 }
11020
11021 static void
11022 store_pair_float (sim_cpu *cpu, int32_t offset, WriteBack wb)
11023 {
11024   unsigned rn = INSTR (14, 10);
11025   unsigned rd = INSTR (9, 5);
11026   unsigned rm = INSTR (4, 0);
11027   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
11028
11029   offset <<= 2;
11030
11031   if (wb != Post)
11032     address += offset;
11033
11034   aarch64_set_mem_u32 (cpu, address,     aarch64_get_vec_u32 (cpu, rm, 0));
11035   aarch64_set_mem_u32 (cpu, address + 4, aarch64_get_vec_u32 (cpu, rn, 0));
11036
11037   if (wb == Post)
11038     address += offset;
11039
11040   if (wb != NoWriteBack)
11041     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
11042 }
11043
11044 static void
11045 store_pair_double (sim_cpu *cpu, int32_t offset, WriteBack wb)
11046 {
11047   unsigned rn = INSTR (14, 10);
11048   unsigned rd = INSTR (9, 5);
11049   unsigned rm = INSTR (4, 0);
11050   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
11051
11052   offset <<= 3;
11053
11054   if (wb != Post)
11055     address += offset;
11056
11057   aarch64_set_mem_u64 (cpu, address,     aarch64_get_vec_u64 (cpu, rm, 0));
11058   aarch64_set_mem_u64 (cpu, address + 8, aarch64_get_vec_u64 (cpu, rn, 0));
11059
11060   if (wb == Post)
11061     address += offset;
11062
11063   if (wb != NoWriteBack)
11064     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
11065 }
11066
11067 static void
11068 store_pair_long_double (sim_cpu *cpu, int32_t offset, WriteBack wb)
11069 {
11070   FRegister a;
11071   unsigned rn = INSTR (14, 10);
11072   unsigned rd = INSTR (9, 5);
11073   unsigned rm = INSTR (4, 0);
11074   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
11075
11076   offset <<= 4;
11077
11078   if (wb != Post)
11079     address += offset;
11080
11081   aarch64_get_FP_long_double (cpu, rm, & a);
11082   aarch64_set_mem_long_double (cpu, address, a);
11083   aarch64_get_FP_long_double (cpu, rn, & a);
11084   aarch64_set_mem_long_double (cpu, address + 16, a);
11085
11086   if (wb == Post)
11087     address += offset;
11088
11089   if (wb != NoWriteBack)
11090     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
11091 }
11092
11093 static void
11094 load_pair_float (sim_cpu *cpu, int32_t offset, WriteBack wb)
11095 {
11096   unsigned rn = INSTR (14, 10);
11097   unsigned rd = INSTR (9, 5);
11098   unsigned rm = INSTR (4, 0);
11099   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
11100
11101   if (rm == rn)
11102     HALT_UNALLOC;
11103
11104   offset <<= 2;
11105
11106   if (wb != Post)
11107     address += offset;
11108
11109   aarch64_set_vec_u32 (cpu, rm, 0, aarch64_get_mem_u32 (cpu, address));
11110   aarch64_set_vec_u32 (cpu, rn, 0, aarch64_get_mem_u32 (cpu, address + 4));
11111
11112   if (wb == Post)
11113     address += offset;
11114
11115   if (wb != NoWriteBack)
11116     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
11117 }
11118
11119 static void
11120 load_pair_double (sim_cpu *cpu, int32_t offset, WriteBack wb)
11121 {
11122   unsigned rn = INSTR (14, 10);
11123   unsigned rd = INSTR (9, 5);
11124   unsigned rm = INSTR (4, 0);
11125   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
11126
11127   if (rm == rn)
11128     HALT_UNALLOC;
11129
11130   offset <<= 3;
11131
11132   if (wb != Post)
11133     address += offset;
11134
11135   aarch64_set_vec_u64 (cpu, rm, 0, aarch64_get_mem_u64 (cpu, address));
11136   aarch64_set_vec_u64 (cpu, rn, 0, aarch64_get_mem_u64 (cpu, address + 8));
11137
11138   if (wb == Post)
11139     address += offset;
11140
11141   if (wb != NoWriteBack)
11142     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
11143 }
11144
11145 static void
11146 load_pair_long_double (sim_cpu *cpu, int32_t offset, WriteBack wb)
11147 {
11148   FRegister a;
11149   unsigned rn = INSTR (14, 10);
11150   unsigned rd = INSTR (9, 5);
11151   unsigned rm = INSTR (4, 0);
11152   uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK);
11153
11154   if (rm == rn)
11155     HALT_UNALLOC;
11156
11157   offset <<= 4;
11158
11159   if (wb != Post)
11160     address += offset;
11161
11162   aarch64_get_mem_long_double (cpu, address, & a);
11163   aarch64_set_FP_long_double (cpu, rm, a);
11164   aarch64_get_mem_long_double (cpu, address + 16, & a);
11165   aarch64_set_FP_long_double (cpu, rn, a);
11166
11167   if (wb == Post)
11168     address += offset;
11169
11170   if (wb != NoWriteBack)
11171     aarch64_set_reg_u64 (cpu, rd, SP_OK, address);
11172 }
11173
11174 static void
11175 dex_load_store_pair_fp (sim_cpu *cpu)
11176 {
11177   /* instr[31,30] = size (10=> 128-bit, 01=> 64-bit, 00=> 32-bit)
11178      instr[29,25] = instruction encoding
11179      instr[24,23] = addressing mode (10=> offset, 01=> post, 11=> pre)
11180      instr[22]    = load/store (1=> load)
11181      instr[21,15] = signed, scaled, offset
11182      instr[14,10] = Rn
11183      instr[ 9, 5] = Rd
11184      instr[ 4, 0] = Rm  */
11185
11186   uint32_t dispatch = ((INSTR (31, 30) << 3) | INSTR (24, 22));
11187   int32_t offset = simm32 (aarch64_get_instr (cpu), 21, 15);
11188
11189   switch (dispatch)
11190     {
11191     case 2: store_pair_float (cpu, offset, Post); return;
11192     case 3: load_pair_float  (cpu, offset, Post); return;
11193     case 4: store_pair_float (cpu, offset, NoWriteBack); return;
11194     case 5: load_pair_float  (cpu, offset, NoWriteBack); return;
11195     case 6: store_pair_float (cpu, offset, Pre); return;
11196     case 7: load_pair_float  (cpu, offset, Pre); return;
11197
11198     case 10: store_pair_double (cpu, offset, Post); return;
11199     case 11: load_pair_double  (cpu, offset, Post); return;
11200     case 12: store_pair_double (cpu, offset, NoWriteBack); return;
11201     case 13: load_pair_double  (cpu, offset, NoWriteBack); return;
11202     case 14: store_pair_double (cpu, offset, Pre); return;
11203     case 15: load_pair_double  (cpu, offset, Pre); return;
11204
11205     case 18: store_pair_long_double (cpu, offset, Post); return;
11206     case 19: load_pair_long_double  (cpu, offset, Post); return;
11207     case 20: store_pair_long_double (cpu, offset, NoWriteBack); return;
11208     case 21: load_pair_long_double  (cpu, offset, NoWriteBack); return;
11209     case 22: store_pair_long_double (cpu, offset, Pre); return;
11210     case 23: load_pair_long_double  (cpu, offset, Pre); return;
11211
11212     default:
11213       HALT_UNALLOC;
11214     }
11215 }
11216
11217 static inline unsigned
11218 vec_reg (unsigned v, unsigned o)
11219 {
11220   return (v + o) & 0x3F;
11221 }
11222
11223 /* Load multiple N-element structures to N consecutive registers.  */
11224 static void
11225 vec_load (sim_cpu *cpu, uint64_t address, unsigned N)
11226 {
11227   int      all  = INSTR (30, 30);
11228   unsigned size = INSTR (11, 10);
11229   unsigned vd   = INSTR (4, 0);
11230   unsigned i;
11231
11232   switch (size)
11233     {
11234     case 0: /* 8-bit operations.  */
11235       if (all)
11236         for (i = 0; i < (16 * N); i++)
11237           aarch64_set_vec_u8 (cpu, vec_reg (vd, i >> 4), i & 15,
11238                               aarch64_get_mem_u8 (cpu, address + i));
11239       else
11240         for (i = 0; i < (8 * N); i++)
11241           aarch64_set_vec_u8 (cpu, vec_reg (vd, i >> 3), i & 7,
11242                               aarch64_get_mem_u8 (cpu, address + i));
11243       return;
11244
11245     case 1: /* 16-bit operations.  */
11246       if (all)
11247         for (i = 0; i < (8 * N); i++)
11248           aarch64_set_vec_u16 (cpu, vec_reg (vd, i >> 3), i & 7,
11249                                aarch64_get_mem_u16 (cpu, address + i * 2));
11250       else
11251         for (i = 0; i < (4 * N); i++)
11252           aarch64_set_vec_u16 (cpu, vec_reg (vd, i >> 2), i & 3,
11253                                aarch64_get_mem_u16 (cpu, address + i * 2));
11254       return;
11255
11256     case 2: /* 32-bit operations.  */
11257       if (all)
11258         for (i = 0; i < (4 * N); i++)
11259           aarch64_set_vec_u32 (cpu, vec_reg (vd, i >> 2), i & 3,
11260                                aarch64_get_mem_u32 (cpu, address + i * 4));
11261       else
11262         for (i = 0; i < (2 * N); i++)
11263           aarch64_set_vec_u32 (cpu, vec_reg (vd, i >> 1), i & 1,
11264                                aarch64_get_mem_u32 (cpu, address + i * 4));
11265       return;
11266
11267     case 3: /* 64-bit operations.  */
11268       if (all)
11269         for (i = 0; i < (2 * N); i++)
11270           aarch64_set_vec_u64 (cpu, vec_reg (vd, i >> 1), i & 1,
11271                                aarch64_get_mem_u64 (cpu, address + i * 8));
11272       else
11273         for (i = 0; i < N; i++)
11274           aarch64_set_vec_u64 (cpu, vec_reg (vd, i), 0,
11275                                aarch64_get_mem_u64 (cpu, address + i * 8));
11276       return;
11277     }
11278 }
11279
11280 /* LD4: load multiple 4-element to four consecutive registers.  */
11281 static void
11282 LD4 (sim_cpu *cpu, uint64_t address)
11283 {
11284   vec_load (cpu, address, 4);
11285 }
11286
11287 /* LD3: load multiple 3-element structures to three consecutive registers.  */
11288 static void
11289 LD3 (sim_cpu *cpu, uint64_t address)
11290 {
11291   vec_load (cpu, address, 3);
11292 }
11293
11294 /* LD2: load multiple 2-element structures to two consecutive registers.  */
11295 static void
11296 LD2 (sim_cpu *cpu, uint64_t address)
11297 {
11298   vec_load (cpu, address, 2);
11299 }
11300
11301 /* Load multiple 1-element structures into one register.  */
11302 static void
11303 LD1_1 (sim_cpu *cpu, uint64_t address)
11304 {
11305   int      all  = INSTR (30, 30);
11306   unsigned size = INSTR (11, 10);
11307   unsigned vd   = INSTR (4, 0);
11308   unsigned i;
11309
11310   switch (size)
11311     {
11312     case 0:
11313       /* LD1 {Vd.16b}, addr, #16 */
11314       /* LD1 {Vd.8b}, addr, #8 */
11315       for (i = 0; i < (all ? 16 : 8); i++)
11316         aarch64_set_vec_u8 (cpu, vd, i,
11317                             aarch64_get_mem_u8 (cpu, address + i));
11318       return;
11319
11320     case 1:
11321       /* LD1 {Vd.8h}, addr, #16 */
11322       /* LD1 {Vd.4h}, addr, #8 */
11323       for (i = 0; i < (all ? 8 : 4); i++)
11324         aarch64_set_vec_u16 (cpu, vd, i,
11325                              aarch64_get_mem_u16 (cpu, address + i * 2));
11326       return;
11327
11328     case 2:
11329       /* LD1 {Vd.4s}, addr, #16 */
11330       /* LD1 {Vd.2s}, addr, #8 */
11331       for (i = 0; i < (all ? 4 : 2); i++)
11332         aarch64_set_vec_u32 (cpu, vd, i,
11333                              aarch64_get_mem_u32 (cpu, address + i * 4));
11334       return;
11335
11336     case 3:
11337       /* LD1 {Vd.2d}, addr, #16 */
11338       /* LD1 {Vd.1d}, addr, #8 */
11339       for (i = 0; i < (all ? 2 : 1); i++)
11340         aarch64_set_vec_u64 (cpu, vd, i,
11341                              aarch64_get_mem_u64 (cpu, address + i * 8));
11342       return;
11343     }
11344 }
11345
11346 /* Load multiple 1-element structures into two registers.  */
11347 static void
11348 LD1_2 (sim_cpu *cpu, uint64_t address)
11349 {
11350   /* FIXME: This algorithm is *exactly* the same as the LD2 version.
11351      So why have two different instructions ?  There must be something
11352      wrong somewhere.  */
11353   vec_load (cpu, address, 2);
11354 }
11355
11356 /* Load multiple 1-element structures into three registers.  */
11357 static void
11358 LD1_3 (sim_cpu *cpu, uint64_t address)
11359 {
11360   /* FIXME: This algorithm is *exactly* the same as the LD3 version.
11361      So why have two different instructions ?  There must be something
11362      wrong somewhere.  */
11363   vec_load (cpu, address, 3);
11364 }
11365
11366 /* Load multiple 1-element structures into four registers.  */
11367 static void
11368 LD1_4 (sim_cpu *cpu, uint64_t address)
11369 {
11370   /* FIXME: This algorithm is *exactly* the same as the LD4 version.
11371      So why have two different instructions ?  There must be something
11372      wrong somewhere.  */
11373   vec_load (cpu, address, 4);
11374 }
11375
11376 /* Store multiple N-element structures to N consecutive registers.  */
11377 static void
11378 vec_store (sim_cpu *cpu, uint64_t address, unsigned N)
11379 {
11380   int      all  = INSTR (30, 30);
11381   unsigned size = INSTR (11, 10);
11382   unsigned vd   = INSTR (4, 0);
11383   unsigned i;
11384
11385   switch (size)
11386     {
11387     case 0: /* 8-bit operations.  */
11388       if (all)
11389         for (i = 0; i < (16 * N); i++)
11390           aarch64_set_mem_u8
11391             (cpu, address + i,
11392              aarch64_get_vec_u8 (cpu, vec_reg (vd, i >> 4), i & 15));
11393       else
11394         for (i = 0; i < (8 * N); i++)
11395           aarch64_set_mem_u8
11396             (cpu, address + i,
11397              aarch64_get_vec_u8 (cpu, vec_reg (vd, i >> 3), i & 7));
11398       return;
11399
11400     case 1: /* 16-bit operations.  */
11401       if (all)
11402         for (i = 0; i < (8 * N); i++)
11403           aarch64_set_mem_u16
11404             (cpu, address + i * 2,
11405              aarch64_get_vec_u16 (cpu, vec_reg (vd, i >> 3), i & 7));
11406       else
11407         for (i = 0; i < (4 * N); i++)
11408           aarch64_set_mem_u16
11409             (cpu, address + i * 2,
11410              aarch64_get_vec_u16 (cpu, vec_reg (vd, i >> 2), i & 3));
11411       return;
11412
11413     case 2: /* 32-bit operations.  */
11414       if (all)
11415         for (i = 0; i < (4 * N); i++)
11416           aarch64_set_mem_u32
11417             (cpu, address + i * 4,
11418              aarch64_get_vec_u32 (cpu, vec_reg (vd, i >> 2), i & 3));
11419       else
11420         for (i = 0; i < (2 * N); i++)
11421           aarch64_set_mem_u32
11422             (cpu, address + i * 4,
11423              aarch64_get_vec_u32 (cpu, vec_reg (vd, i >> 1), i & 1));
11424       return;
11425
11426     case 3: /* 64-bit operations.  */
11427       if (all)
11428         for (i = 0; i < (2 * N); i++)
11429           aarch64_set_mem_u64
11430             (cpu, address + i * 8,
11431              aarch64_get_vec_u64 (cpu, vec_reg (vd, i >> 1), i & 1));
11432       else
11433         for (i = 0; i < N; i++)
11434           aarch64_set_mem_u64
11435             (cpu, address + i * 8,
11436              aarch64_get_vec_u64 (cpu, vec_reg (vd, i), 0));
11437       return;
11438     }
11439 }
11440
11441 /* Store multiple 4-element structure to four consecutive registers.  */
11442 static void
11443 ST4 (sim_cpu *cpu, uint64_t address)
11444 {
11445   vec_store (cpu, address, 4);
11446 }
11447
11448 /* Store multiple 3-element structures to three consecutive registers.  */
11449 static void
11450 ST3 (sim_cpu *cpu, uint64_t address)
11451 {
11452   vec_store (cpu, address, 3);
11453 }
11454
11455 /* Store multiple 2-element structures to two consecutive registers.  */
11456 static void
11457 ST2 (sim_cpu *cpu, uint64_t address)
11458 {
11459   vec_store (cpu, address, 2);
11460 }
11461
11462 /* Store multiple 1-element structures into one register.  */
11463 static void
11464 ST1_1 (sim_cpu *cpu, uint64_t address)
11465 {
11466   int      all  = INSTR (30, 30);
11467   unsigned size = INSTR (11, 10);
11468   unsigned vd   = INSTR (4, 0);
11469   unsigned i;
11470
11471   switch (size)
11472     {
11473     case 0:
11474       for (i = 0; i < (all ? 16 : 8); i++)
11475         aarch64_set_mem_u8 (cpu, address + i,
11476                             aarch64_get_vec_u8 (cpu, vd, i));
11477       return;
11478
11479     case 1:
11480       for (i = 0; i < (all ? 8 : 4); i++)
11481         aarch64_set_mem_u16 (cpu, address + i * 2,
11482                              aarch64_get_vec_u16 (cpu, vd, i));
11483       return;
11484
11485     case 2:
11486       for (i = 0; i < (all ? 4 : 2); i++)
11487         aarch64_set_mem_u32 (cpu, address + i * 4,
11488                              aarch64_get_vec_u32 (cpu, vd, i));
11489       return;
11490
11491     case 3:
11492       for (i = 0; i < (all ? 2 : 1); i++)
11493         aarch64_set_mem_u64 (cpu, address + i * 8,
11494                              aarch64_get_vec_u64 (cpu, vd, i));
11495       return;
11496     }
11497 }
11498
11499 /* Store multiple 1-element structures into two registers.  */
11500 static void
11501 ST1_2 (sim_cpu *cpu, uint64_t address)
11502 {
11503   /* FIXME: This algorithm is *exactly* the same as the ST2 version.
11504      So why have two different instructions ?  There must be
11505      something wrong somewhere.  */
11506   vec_store (cpu, address, 2);
11507 }
11508
11509 /* Store multiple 1-element structures into three registers.  */
11510 static void
11511 ST1_3 (sim_cpu *cpu, uint64_t address)
11512 {
11513   /* FIXME: This algorithm is *exactly* the same as the ST3 version.
11514      So why have two different instructions ?  There must be
11515      something wrong somewhere.  */
11516   vec_store (cpu, address, 3);
11517 }
11518
11519 /* Store multiple 1-element structures into four registers.  */
11520 static void
11521 ST1_4 (sim_cpu *cpu, uint64_t address)
11522 {
11523   /* FIXME: This algorithm is *exactly* the same as the ST4 version.
11524      So why have two different instructions ?  There must be
11525      something wrong somewhere.  */
11526   vec_store (cpu, address, 4);
11527 }
11528
11529 static void
11530 do_vec_LDnR (sim_cpu *cpu, uint64_t address)
11531 {
11532   /* instr[31]    = 0
11533      instr[30]    = element selector 0=>half, 1=>all elements
11534      instr[29,24] = 00 1101
11535      instr[23]    = 0=>simple, 1=>post
11536      instr[22]    = 1
11537      instr[21]    = width: LD1R-or-LD3R (0) / LD2R-or-LD4R (1)
11538      instr[20,16] = 0 0000 (simple), Vinc (reg-post-inc, no SP),
11539                       11111 (immediate post inc)
11540      instr[15,14] = 11
11541      instr[13]    = width: LD1R-or-LD2R (0) / LD3R-or-LD4R (1)
11542      instr[12]    = 0
11543      instr[11,10] = element size 00=> byte(b), 01=> half(h),
11544                                  10=> word(s), 11=> double(d)
11545      instr[9,5]   = address
11546      instr[4,0]   = Vd  */
11547
11548   unsigned full = INSTR (30, 30);
11549   unsigned vd = INSTR (4, 0);
11550   unsigned size = INSTR (11, 10);
11551   int i;
11552
11553   NYI_assert (29, 24, 0x0D);
11554   NYI_assert (22, 22, 1);
11555   NYI_assert (15, 14, 3);
11556   NYI_assert (12, 12, 0);
11557
11558   switch ((INSTR (13, 13) << 1) | INSTR (21, 21))
11559     {
11560     case 0: /* LD1R.  */
11561       switch (size)
11562         {
11563         case 0:
11564           {
11565             uint8_t val = aarch64_get_mem_u8 (cpu, address);
11566             for (i = 0; i < (full ? 16 : 8); i++)
11567               aarch64_set_vec_u8 (cpu, vd, i, val);
11568             break;
11569           }
11570
11571         case 1:
11572           {
11573             uint16_t val = aarch64_get_mem_u16 (cpu, address);
11574             for (i = 0; i < (full ? 8 : 4); i++)
11575               aarch64_set_vec_u16 (cpu, vd, i, val);
11576             break;
11577           }
11578
11579         case 2:
11580           {
11581             uint32_t val = aarch64_get_mem_u32 (cpu, address);
11582             for (i = 0; i < (full ? 4 : 2); i++)
11583               aarch64_set_vec_u32 (cpu, vd, i, val);
11584             break;
11585           }
11586
11587         case 3:
11588           {
11589             uint64_t val = aarch64_get_mem_u64 (cpu, address);
11590             for (i = 0; i < (full ? 2 : 1); i++)
11591               aarch64_set_vec_u64 (cpu, vd, i, val);
11592             break;
11593           }
11594
11595         default:
11596           HALT_UNALLOC;
11597         }
11598       break;
11599
11600     case 1: /* LD2R.  */
11601       switch (size)
11602         {
11603         case 0:
11604           {
11605             uint8_t val1 = aarch64_get_mem_u8 (cpu, address);
11606             uint8_t val2 = aarch64_get_mem_u8 (cpu, address + 1);
11607
11608             for (i = 0; i < (full ? 16 : 8); i++)
11609               {
11610                 aarch64_set_vec_u8 (cpu, vd, 0, val1);
11611                 aarch64_set_vec_u8 (cpu, vd + 1, 0, val2);
11612               }
11613             break;
11614           }
11615
11616         case 1:
11617           {
11618             uint16_t val1 = aarch64_get_mem_u16 (cpu, address);
11619             uint16_t val2 = aarch64_get_mem_u16 (cpu, address + 2);
11620
11621             for (i = 0; i < (full ? 8 : 4); i++)
11622               {
11623                 aarch64_set_vec_u16 (cpu, vd, 0, val1);
11624                 aarch64_set_vec_u16 (cpu, vd + 1, 0, val2);
11625               }
11626             break;
11627           }
11628
11629         case 2:
11630           {
11631             uint32_t val1 = aarch64_get_mem_u32 (cpu, address);
11632             uint32_t val2 = aarch64_get_mem_u32 (cpu, address + 4);
11633
11634             for (i = 0; i < (full ? 4 : 2); i++)
11635               {
11636                 aarch64_set_vec_u32 (cpu, vd, 0, val1);
11637                 aarch64_set_vec_u32 (cpu, vd + 1, 0, val2);
11638               }
11639             break;
11640           }
11641
11642         case 3:
11643           {
11644             uint64_t val1 = aarch64_get_mem_u64 (cpu, address);
11645             uint64_t val2 = aarch64_get_mem_u64 (cpu, address + 8);
11646
11647             for (i = 0; i < (full ? 2 : 1); i++)
11648               {
11649                 aarch64_set_vec_u64 (cpu, vd, 0, val1);
11650                 aarch64_set_vec_u64 (cpu, vd + 1, 0, val2);
11651               }
11652             break;
11653           }
11654
11655         default:
11656           HALT_UNALLOC;
11657         }
11658       break;
11659
11660     case 2: /* LD3R.  */
11661       switch (size)
11662         {
11663         case 0:
11664           {
11665             uint8_t val1 = aarch64_get_mem_u8 (cpu, address);
11666             uint8_t val2 = aarch64_get_mem_u8 (cpu, address + 1);
11667             uint8_t val3 = aarch64_get_mem_u8 (cpu, address + 2);
11668
11669             for (i = 0; i < (full ? 16 : 8); i++)
11670               {
11671                 aarch64_set_vec_u8 (cpu, vd, 0, val1);
11672                 aarch64_set_vec_u8 (cpu, vd + 1, 0, val2);
11673                 aarch64_set_vec_u8 (cpu, vd + 2, 0, val3);
11674               }
11675           }
11676           break;
11677
11678         case 1:
11679           {
11680             uint32_t val1 = aarch64_get_mem_u16 (cpu, address);
11681             uint32_t val2 = aarch64_get_mem_u16 (cpu, address + 2);
11682             uint32_t val3 = aarch64_get_mem_u16 (cpu, address + 4);
11683
11684             for (i = 0; i < (full ? 8 : 4); i++)
11685               {
11686                 aarch64_set_vec_u16 (cpu, vd, 0, val1);
11687                 aarch64_set_vec_u16 (cpu, vd + 1, 0, val2);
11688                 aarch64_set_vec_u16 (cpu, vd + 2, 0, val3);
11689               }
11690           }
11691           break;
11692
11693         case 2:
11694           {
11695             uint32_t val1 = aarch64_get_mem_u32 (cpu, address);
11696             uint32_t val2 = aarch64_get_mem_u32 (cpu, address + 4);
11697             uint32_t val3 = aarch64_get_mem_u32 (cpu, address + 8);
11698
11699             for (i = 0; i < (full ? 4 : 2); i++)
11700               {
11701                 aarch64_set_vec_u32 (cpu, vd, 0, val1);
11702                 aarch64_set_vec_u32 (cpu, vd + 1, 0, val2);
11703                 aarch64_set_vec_u32 (cpu, vd + 2, 0, val3);
11704               }
11705           }
11706           break;
11707
11708         case 3:
11709           {
11710             uint64_t val1 = aarch64_get_mem_u64 (cpu, address);
11711             uint64_t val2 = aarch64_get_mem_u64 (cpu, address + 8);
11712             uint64_t val3 = aarch64_get_mem_u64 (cpu, address + 16);
11713
11714             for (i = 0; i < (full ? 2 : 1); i++)
11715               {
11716                 aarch64_set_vec_u64 (cpu, vd, 0, val1);
11717                 aarch64_set_vec_u64 (cpu, vd + 1, 0, val2);
11718                 aarch64_set_vec_u64 (cpu, vd + 2, 0, val3);
11719               }
11720           }
11721           break;
11722
11723         default:
11724           HALT_UNALLOC;
11725         }
11726       break;
11727
11728     case 3: /* LD4R.  */
11729       switch (size)
11730         {
11731         case 0:
11732           {
11733             uint8_t val1 = aarch64_get_mem_u8 (cpu, address);
11734             uint8_t val2 = aarch64_get_mem_u8 (cpu, address + 1);
11735             uint8_t val3 = aarch64_get_mem_u8 (cpu, address + 2);
11736             uint8_t val4 = aarch64_get_mem_u8 (cpu, address + 3);
11737
11738             for (i = 0; i < (full ? 16 : 8); i++)
11739               {
11740                 aarch64_set_vec_u8 (cpu, vd, 0, val1);
11741                 aarch64_set_vec_u8 (cpu, vd + 1, 0, val2);
11742                 aarch64_set_vec_u8 (cpu, vd + 2, 0, val3);
11743                 aarch64_set_vec_u8 (cpu, vd + 3, 0, val4);
11744               }
11745           }
11746           break;
11747
11748         case 1:
11749           {
11750             uint32_t val1 = aarch64_get_mem_u16 (cpu, address);
11751             uint32_t val2 = aarch64_get_mem_u16 (cpu, address + 2);
11752             uint32_t val3 = aarch64_get_mem_u16 (cpu, address + 4);
11753             uint32_t val4 = aarch64_get_mem_u16 (cpu, address + 6);
11754
11755             for (i = 0; i < (full ? 8 : 4); i++)
11756               {
11757                 aarch64_set_vec_u16 (cpu, vd, 0, val1);
11758                 aarch64_set_vec_u16 (cpu, vd + 1, 0, val2);
11759                 aarch64_set_vec_u16 (cpu, vd + 2, 0, val3);
11760                 aarch64_set_vec_u16 (cpu, vd + 3, 0, val4);
11761               }
11762           }
11763           break;
11764
11765         case 2:
11766           {
11767             uint32_t val1 = aarch64_get_mem_u32 (cpu, address);
11768             uint32_t val2 = aarch64_get_mem_u32 (cpu, address + 4);
11769             uint32_t val3 = aarch64_get_mem_u32 (cpu, address + 8);
11770             uint32_t val4 = aarch64_get_mem_u32 (cpu, address + 12);
11771
11772             for (i = 0; i < (full ? 4 : 2); i++)
11773               {
11774                 aarch64_set_vec_u32 (cpu, vd, 0, val1);
11775                 aarch64_set_vec_u32 (cpu, vd + 1, 0, val2);
11776                 aarch64_set_vec_u32 (cpu, vd + 2, 0, val3);
11777                 aarch64_set_vec_u32 (cpu, vd + 3, 0, val4);
11778               }
11779           }
11780           break;
11781
11782         case 3:
11783           {
11784             uint64_t val1 = aarch64_get_mem_u64 (cpu, address);
11785             uint64_t val2 = aarch64_get_mem_u64 (cpu, address + 8);
11786             uint64_t val3 = aarch64_get_mem_u64 (cpu, address + 16);
11787             uint64_t val4 = aarch64_get_mem_u64 (cpu, address + 24);
11788
11789             for (i = 0; i < (full ? 2 : 1); i++)
11790               {
11791                 aarch64_set_vec_u64 (cpu, vd, 0, val1);
11792                 aarch64_set_vec_u64 (cpu, vd + 1, 0, val2);
11793                 aarch64_set_vec_u64 (cpu, vd + 2, 0, val3);
11794                 aarch64_set_vec_u64 (cpu, vd + 3, 0, val4);
11795               }
11796           }
11797           break;
11798
11799         default:
11800           HALT_UNALLOC;
11801         }
11802       break;
11803
11804     default:
11805       HALT_UNALLOC;
11806     }
11807 }
11808
11809 static void
11810 do_vec_load_store (sim_cpu *cpu)
11811 {
11812   /* {LD|ST}<N>   {Vd..Vd+N}, vaddr
11813
11814      instr[31]    = 0
11815      instr[30]    = element selector 0=>half, 1=>all elements
11816      instr[29,25] = 00110
11817      instr[24]    = ?
11818      instr[23]    = 0=>simple, 1=>post
11819      instr[22]    = 0=>store, 1=>load
11820      instr[21]    = 0 (LDn) / small(0)-large(1) selector (LDnR)
11821      instr[20,16] = 00000 (simple), Vinc (reg-post-inc, no SP),
11822                     11111 (immediate post inc)
11823      instr[15,12] = elements and destinations.  eg for load:
11824                      0000=>LD4 => load multiple 4-element to
11825                      four consecutive registers
11826                      0100=>LD3 => load multiple 3-element to
11827                      three consecutive registers
11828                      1000=>LD2 => load multiple 2-element to
11829                      two consecutive registers
11830                      0010=>LD1 => load multiple 1-element to
11831                      four consecutive registers
11832                      0110=>LD1 => load multiple 1-element to
11833                      three consecutive registers
11834                      1010=>LD1 => load multiple 1-element to
11835                      two consecutive registers
11836                      0111=>LD1 => load multiple 1-element to
11837                      one register
11838                      1100=>LDR1,LDR2
11839                      1110=>LDR3,LDR4
11840      instr[11,10] = element size 00=> byte(b), 01=> half(h),
11841                                  10=> word(s), 11=> double(d)
11842      instr[9,5]   = Vn, can be SP
11843      instr[4,0]   = Vd  */
11844
11845   int post;
11846   int load;
11847   unsigned vn;
11848   uint64_t address;
11849   int type;
11850
11851   if (INSTR (31, 31) != 0 || INSTR (29, 25) != 0x06)
11852     HALT_NYI;
11853
11854   type = INSTR (15, 12);
11855   if (type != 0xE && type != 0xE && INSTR (21, 21) != 0)
11856     HALT_NYI;
11857
11858   post = INSTR (23, 23);
11859   load = INSTR (22, 22);
11860   vn = INSTR (9, 5);
11861   address = aarch64_get_reg_u64 (cpu, vn, SP_OK);
11862
11863   if (post)
11864     {
11865       unsigned vm = INSTR (20, 16);
11866
11867       if (vm == R31)
11868         {
11869           unsigned sizeof_operation;
11870
11871           switch (type)
11872             {
11873             case 0: sizeof_operation = 32; break;
11874             case 4: sizeof_operation = 24; break;
11875             case 8: sizeof_operation = 16; break;
11876
11877             case 0xC:
11878               sizeof_operation = INSTR (21, 21) ? 2 : 1;
11879               sizeof_operation <<= INSTR (11, 10);
11880               break;
11881
11882             case 0xE:
11883               sizeof_operation = INSTR (21, 21) ? 8 : 4;
11884               sizeof_operation <<= INSTR (11, 10);
11885               break;
11886
11887             case 7:
11888               /* One register, immediate offset variant.  */
11889               sizeof_operation = 8;
11890               break;
11891
11892             case 10:
11893               /* Two registers, immediate offset variant.  */
11894               sizeof_operation = 16;
11895               break;
11896
11897             case 6:
11898               /* Three registers, immediate offset variant.  */
11899               sizeof_operation = 24;
11900               break;
11901
11902             case 2:
11903               /* Four registers, immediate offset variant.  */
11904               sizeof_operation = 32;
11905               break;
11906
11907             default:
11908               HALT_UNALLOC;
11909             }
11910
11911           if (INSTR (30, 30))
11912             sizeof_operation *= 2;
11913
11914           aarch64_set_reg_u64 (cpu, vn, SP_OK, address + sizeof_operation);
11915         }
11916       else
11917         aarch64_set_reg_u64 (cpu, vn, SP_OK,
11918                              address + aarch64_get_reg_u64 (cpu, vm, NO_SP));
11919     }
11920   else
11921     {
11922       NYI_assert (20, 16, 0);
11923     }
11924
11925   if (load)
11926     {
11927       switch (type)
11928         {
11929         case 0:  LD4 (cpu, address); return;
11930         case 4:  LD3 (cpu, address); return;
11931         case 8:  LD2 (cpu, address); return;
11932         case 2:  LD1_4 (cpu, address); return;
11933         case 6:  LD1_3 (cpu, address); return;
11934         case 10: LD1_2 (cpu, address); return;
11935         case 7:  LD1_1 (cpu, address); return;
11936
11937         case 0xE:
11938         case 0xC: do_vec_LDnR (cpu, address); return;
11939
11940         default:
11941           HALT_NYI;
11942         }
11943     }
11944
11945   /* Stores.  */
11946   switch (type)
11947     {
11948     case 0:  ST4 (cpu, address); return;
11949     case 4:  ST3 (cpu, address); return;
11950     case 8:  ST2 (cpu, address); return;
11951     case 2:  ST1_4 (cpu, address); return;
11952     case 6:  ST1_3 (cpu, address); return;
11953     case 10: ST1_2 (cpu, address); return;
11954     case 7:  ST1_1 (cpu, address); return;
11955     default:
11956       HALT_NYI;
11957     }
11958 }
11959
11960 static void
11961 dexLdSt (sim_cpu *cpu)
11962 {
11963   /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu));
11964      assert  group == GROUP_LDST_0100 || group == GROUP_LDST_0110 ||
11965              group == GROUP_LDST_1100 || group == GROUP_LDST_1110
11966      bits [29,28:26] of a LS are the secondary dispatch vector.  */
11967   uint32_t group2 = dispatchLS (aarch64_get_instr (cpu));
11968
11969   switch (group2)
11970     {
11971     case LS_EXCL_000:
11972       dexLoadExclusive (cpu); return;
11973
11974     case LS_LIT_010:
11975     case LS_LIT_011:
11976       dexLoadLiteral (cpu); return;
11977
11978     case LS_OTHER_110:
11979     case LS_OTHER_111:
11980       dexLoadOther (cpu); return;
11981
11982     case LS_ADVSIMD_001:
11983       do_vec_load_store (cpu); return;
11984
11985     case LS_PAIR_100:
11986       dex_load_store_pair_gr (cpu); return;
11987
11988     case LS_PAIR_101:
11989       dex_load_store_pair_fp (cpu); return;
11990
11991     default:
11992       /* Should never reach here.  */
11993       HALT_NYI;
11994     }
11995 }
11996
11997 /* Specific decode and execute for group Data Processing Register.  */
11998
11999 static void
12000 dexLogicalShiftedRegister (sim_cpu *cpu)
12001 {
12002   /* instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
12003      instr[30,29] = op
12004      instr[28:24] = 01010
12005      instr[23,22] = shift : 0 ==> LSL, 1 ==> LSR, 2 ==> ASR, 3 ==> ROR
12006      instr[21]    = N
12007      instr[20,16] = Rm
12008      instr[15,10] = count : must be 0xxxxx for 32 bit
12009      instr[9,5]   = Rn
12010      instr[4,0]   = Rd  */
12011
12012   uint32_t size      = INSTR (31, 31);
12013   Shift    shiftType = INSTR (23, 22);
12014   uint32_t count     = INSTR (15, 10);
12015
12016   /* 32 bit operations must have count[5] = 0.
12017      or else we have an UNALLOC.  */
12018   if (size == 0 && uimm (count, 5, 5))
12019     HALT_UNALLOC;
12020
12021   /* Dispatch on size:op:N.  */
12022   switch ((INSTR (31, 29) << 1) | INSTR (21, 21))
12023     {
12024     case 0: and32_shift  (cpu, shiftType, count); return;
12025     case 1: bic32_shift  (cpu, shiftType, count); return;
12026     case 2: orr32_shift  (cpu, shiftType, count); return;
12027     case 3: orn32_shift  (cpu, shiftType, count); return;
12028     case 4: eor32_shift  (cpu, shiftType, count); return;
12029     case 5: eon32_shift  (cpu, shiftType, count); return;
12030     case 6: ands32_shift (cpu, shiftType, count); return;
12031     case 7: bics32_shift (cpu, shiftType, count); return;
12032     case 8: and64_shift  (cpu, shiftType, count); return;
12033     case 9: bic64_shift  (cpu, shiftType, count); return;
12034     case 10:orr64_shift  (cpu, shiftType, count); return;
12035     case 11:orn64_shift  (cpu, shiftType, count); return;
12036     case 12:eor64_shift  (cpu, shiftType, count); return;
12037     case 13:eon64_shift  (cpu, shiftType, count); return;
12038     case 14:ands64_shift (cpu, shiftType, count); return;
12039     case 15:bics64_shift (cpu, shiftType, count); return;
12040     }
12041 }
12042
12043 /* 32 bit conditional select.  */
12044 static void
12045 csel32 (sim_cpu *cpu, CondCode cc)
12046 {
12047   unsigned rm = INSTR (20, 16);
12048   unsigned rn = INSTR (9, 5);
12049   unsigned rd = INSTR (4, 0);
12050
12051   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12052                        testConditionCode (cpu, cc)
12053                        ? aarch64_get_reg_u32 (cpu, rn, NO_SP)
12054                        : aarch64_get_reg_u32 (cpu, rm, NO_SP));
12055 }
12056
12057 /* 64 bit conditional select.  */
12058 static void
12059 csel64 (sim_cpu *cpu, CondCode cc)
12060 {
12061   unsigned rm = INSTR (20, 16);
12062   unsigned rn = INSTR (9, 5);
12063   unsigned rd = INSTR (4, 0);
12064
12065   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12066                        testConditionCode (cpu, cc)
12067                        ? aarch64_get_reg_u64 (cpu, rn, NO_SP)
12068                        : aarch64_get_reg_u64 (cpu, rm, NO_SP));
12069 }
12070
12071 /* 32 bit conditional increment.  */
12072 static void
12073 csinc32 (sim_cpu *cpu, CondCode cc)
12074 {
12075   unsigned rm = INSTR (20, 16);
12076   unsigned rn = INSTR (9, 5);
12077   unsigned rd = INSTR (4, 0);
12078
12079   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12080                        testConditionCode (cpu, cc)
12081                        ? aarch64_get_reg_u32 (cpu, rn, NO_SP)
12082                        : aarch64_get_reg_u32 (cpu, rm, NO_SP) + 1);
12083 }
12084
12085 /* 64 bit conditional increment.  */
12086 static void
12087 csinc64 (sim_cpu *cpu, CondCode cc)
12088 {
12089   unsigned rm = INSTR (20, 16);
12090   unsigned rn = INSTR (9, 5);
12091   unsigned rd = INSTR (4, 0);
12092
12093   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12094                        testConditionCode (cpu, cc)
12095                        ? aarch64_get_reg_u64 (cpu, rn, NO_SP)
12096                        : aarch64_get_reg_u64 (cpu, rm, NO_SP) + 1);
12097 }
12098
12099 /* 32 bit conditional invert.  */
12100 static void
12101 csinv32 (sim_cpu *cpu, CondCode cc)
12102 {
12103   unsigned rm = INSTR (20, 16);
12104   unsigned rn = INSTR (9, 5);
12105   unsigned rd = INSTR (4, 0);
12106
12107   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12108                        testConditionCode (cpu, cc)
12109                        ? aarch64_get_reg_u32 (cpu, rn, NO_SP)
12110                        : ~ aarch64_get_reg_u32 (cpu, rm, NO_SP));
12111 }
12112
12113 /* 64 bit conditional invert.  */
12114 static void
12115 csinv64 (sim_cpu *cpu, CondCode cc)
12116 {
12117   unsigned rm = INSTR (20, 16);
12118   unsigned rn = INSTR (9, 5);
12119   unsigned rd = INSTR (4, 0);
12120
12121   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12122                        testConditionCode (cpu, cc)
12123                        ? aarch64_get_reg_u64 (cpu, rn, NO_SP)
12124                        : ~ aarch64_get_reg_u64 (cpu, rm, NO_SP));
12125 }
12126
12127 /* 32 bit conditional negate.  */
12128 static void
12129 csneg32 (sim_cpu *cpu, CondCode cc)
12130 {
12131   unsigned rm = INSTR (20, 16);
12132   unsigned rn = INSTR (9, 5);
12133   unsigned rd = INSTR (4, 0);
12134
12135   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12136                        testConditionCode (cpu, cc)
12137                        ? aarch64_get_reg_u32 (cpu, rn, NO_SP)
12138                        : - aarch64_get_reg_u32 (cpu, rm, NO_SP));
12139 }
12140
12141 /* 64 bit conditional negate.  */
12142 static void
12143 csneg64 (sim_cpu *cpu, CondCode cc)
12144 {
12145   unsigned rm = INSTR (20, 16);
12146   unsigned rn = INSTR (9, 5);
12147   unsigned rd = INSTR (4, 0);
12148
12149   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12150                        testConditionCode (cpu, cc)
12151                        ? aarch64_get_reg_u64 (cpu, rn, NO_SP)
12152                        : - aarch64_get_reg_u64 (cpu, rm, NO_SP));
12153 }
12154
12155 static void
12156 dexCondSelect (sim_cpu *cpu)
12157 {
12158   /* instr[28,21] = 11011011
12159      instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
12160      instr[30:11,10] = op : 000 ==> CSEL, 001 ==> CSINC,
12161                             100 ==> CSINV, 101 ==> CSNEG,
12162                             _1_ ==> UNALLOC
12163      instr[29] = S : 0 ==> ok, 1 ==> UNALLOC
12164      instr[15,12] = cond
12165      instr[29] = S : 0 ==> ok, 1 ==> UNALLOC  */
12166
12167   CondCode cc = INSTR (15, 12);
12168   uint32_t S = INSTR (29, 29);
12169   uint32_t op2 = INSTR (11, 10);
12170
12171   if (S == 1)
12172     HALT_UNALLOC;
12173
12174   if (op2 & 0x2)
12175     HALT_UNALLOC;
12176
12177   switch ((INSTR (31, 30) << 1) | op2)
12178     {
12179     case 0: csel32  (cpu, cc); return;
12180     case 1: csinc32 (cpu, cc); return;
12181     case 2: csinv32 (cpu, cc); return;
12182     case 3: csneg32 (cpu, cc); return;
12183     case 4: csel64  (cpu, cc); return;
12184     case 5: csinc64 (cpu, cc); return;
12185     case 6: csinv64 (cpu, cc); return;
12186     case 7: csneg64 (cpu, cc); return;
12187     }
12188 }
12189
12190 /* Some helpers for counting leading 1 or 0 bits.  */
12191
12192 /* Counts the number of leading bits which are the same
12193    in a 32 bit value in the range 1 to 32.  */
12194 static uint32_t
12195 leading32 (uint32_t value)
12196 {
12197   int32_t mask= 0xffff0000;
12198   uint32_t count= 16; /* Counts number of bits set in mask.  */
12199   uint32_t lo = 1;    /* Lower bound for number of sign bits.  */
12200   uint32_t hi = 32;   /* Upper bound for number of sign bits.  */
12201
12202   while (lo + 1 < hi)
12203     {
12204       int32_t test = (value & mask);
12205
12206       if (test == 0 || test == mask)
12207         {
12208           lo = count;
12209           count = (lo + hi) / 2;
12210           mask >>= (count - lo);
12211         }
12212       else
12213         {
12214           hi = count;
12215           count = (lo + hi) / 2;
12216           mask <<= hi - count;
12217         }
12218     }
12219
12220   if (lo != hi)
12221     {
12222       int32_t test;
12223
12224       mask >>= 1;
12225       test = (value & mask);
12226
12227       if (test == 0 || test == mask)
12228         count = hi;
12229       else
12230         count = lo;
12231     }
12232
12233   return count;
12234 }
12235
12236 /* Counts the number of leading bits which are the same
12237    in a 64 bit value in the range 1 to 64.  */
12238 static uint64_t
12239 leading64 (uint64_t value)
12240 {
12241   int64_t mask= 0xffffffff00000000LL;
12242   uint64_t count = 32; /* Counts number of bits set in mask.  */
12243   uint64_t lo = 1;     /* Lower bound for number of sign bits.  */
12244   uint64_t hi = 64;    /* Upper bound for number of sign bits.  */
12245
12246   while (lo + 1 < hi)
12247     {
12248       int64_t test = (value & mask);
12249
12250       if (test == 0 || test == mask)
12251         {
12252           lo = count;
12253           count = (lo + hi) / 2;
12254           mask >>= (count - lo);
12255         }
12256       else
12257         {
12258           hi = count;
12259           count = (lo + hi) / 2;
12260           mask <<= hi - count;
12261         }
12262     }
12263
12264   if (lo != hi)
12265     {
12266       int64_t test;
12267
12268       mask >>= 1;
12269       test = (value & mask);
12270
12271       if (test == 0 || test == mask)
12272         count = hi;
12273       else
12274         count = lo;
12275     }
12276
12277   return count;
12278 }
12279
12280 /* Bit operations.  */
12281 /* N.B register args may not be SP.  */
12282
12283 /* 32 bit count leading sign bits.  */
12284 static void
12285 cls32 (sim_cpu *cpu)
12286 {
12287   unsigned rn = INSTR (9, 5);
12288   unsigned rd = INSTR (4, 0);
12289
12290   /* N.B. the result needs to exclude the leading bit.  */
12291   aarch64_set_reg_u64
12292     (cpu, rd, NO_SP, leading32 (aarch64_get_reg_u32 (cpu, rn, NO_SP)) - 1);
12293 }
12294
12295 /* 64 bit count leading sign bits.  */
12296 static void
12297 cls64 (sim_cpu *cpu)
12298 {
12299   unsigned rn = INSTR (9, 5);
12300   unsigned rd = INSTR (4, 0);
12301
12302   /* N.B. the result needs to exclude the leading bit.  */
12303   aarch64_set_reg_u64
12304     (cpu, rd, NO_SP, leading64 (aarch64_get_reg_u64 (cpu, rn, NO_SP)) - 1);
12305 }
12306
12307 /* 32 bit count leading zero bits.  */
12308 static void
12309 clz32 (sim_cpu *cpu)
12310 {
12311   unsigned rn = INSTR (9, 5);
12312   unsigned rd = INSTR (4, 0);
12313   uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
12314
12315   /* if the sign (top) bit is set then the count is 0.  */
12316   if (pick32 (value, 31, 31))
12317     aarch64_set_reg_u64 (cpu, rd, NO_SP, 0L);
12318   else
12319     aarch64_set_reg_u64 (cpu, rd, NO_SP, leading32 (value));
12320 }
12321
12322 /* 64 bit count leading zero bits.  */
12323 static void
12324 clz64 (sim_cpu *cpu)
12325 {
12326   unsigned rn = INSTR (9, 5);
12327   unsigned rd = INSTR (4, 0);
12328   uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
12329
12330   /* if the sign (top) bit is set then the count is 0.  */
12331   if (pick64 (value, 63, 63))
12332     aarch64_set_reg_u64 (cpu, rd, NO_SP, 0L);
12333   else
12334     aarch64_set_reg_u64 (cpu, rd, NO_SP, leading64 (value));
12335 }
12336
12337 /* 32 bit reverse bits.  */
12338 static void
12339 rbit32 (sim_cpu *cpu)
12340 {
12341   unsigned rn = INSTR (9, 5);
12342   unsigned rd = INSTR (4, 0);
12343   uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
12344   uint32_t result = 0;
12345   int i;
12346
12347   for (i = 0; i < 32; i++)
12348     {
12349       result <<= 1;
12350       result |= (value & 1);
12351       value >>= 1;
12352     }
12353   aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
12354 }
12355
12356 /* 64 bit reverse bits.  */
12357 static void
12358 rbit64 (sim_cpu *cpu)
12359 {
12360   unsigned rn = INSTR (9, 5);
12361   unsigned rd = INSTR (4, 0);
12362   uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
12363   uint64_t result = 0;
12364   int i;
12365
12366   for (i = 0; i < 64; i++)
12367     {
12368       result <<= 1;
12369       result |= (value & 1UL);
12370       value >>= 1;
12371     }
12372   aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
12373 }
12374
12375 /* 32 bit reverse bytes.  */
12376 static void
12377 rev32 (sim_cpu *cpu)
12378 {
12379   unsigned rn = INSTR (9, 5);
12380   unsigned rd = INSTR (4, 0);
12381   uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
12382   uint32_t result = 0;
12383   int i;
12384
12385   for (i = 0; i < 4; i++)
12386     {
12387       result <<= 8;
12388       result |= (value & 0xff);
12389       value >>= 8;
12390     }
12391   aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
12392 }
12393
12394 /* 64 bit reverse bytes.  */
12395 static void
12396 rev64 (sim_cpu *cpu)
12397 {
12398   unsigned rn = INSTR (9, 5);
12399   unsigned rd = INSTR (4, 0);
12400   uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
12401   uint64_t result = 0;
12402   int i;
12403
12404   for (i = 0; i < 8; i++)
12405     {
12406       result <<= 8;
12407       result |= (value & 0xffULL);
12408       value >>= 8;
12409     }
12410   aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
12411 }
12412
12413 /* 32 bit reverse shorts.  */
12414 /* N.B.this reverses the order of the bytes in each half word.  */
12415 static void
12416 revh32 (sim_cpu *cpu)
12417 {
12418   unsigned rn = INSTR (9, 5);
12419   unsigned rd = INSTR (4, 0);
12420   uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP);
12421   uint32_t result = 0;
12422   int i;
12423
12424   for (i = 0; i < 2; i++)
12425     {
12426       result <<= 8;
12427       result |= (value & 0x00ff00ff);
12428       value >>= 8;
12429     }
12430   aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
12431 }
12432
12433 /* 64 bit reverse shorts.  */
12434 /* N.B.this reverses the order of the bytes in each half word.  */
12435 static void
12436 revh64 (sim_cpu *cpu)
12437 {
12438   unsigned rn = INSTR (9, 5);
12439   unsigned rd = INSTR (4, 0);
12440   uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP);
12441   uint64_t result = 0;
12442   int i;
12443
12444   for (i = 0; i < 2; i++)
12445     {
12446       result <<= 8;
12447       result |= (value & 0x00ff00ff00ff00ffULL);
12448       value >>= 8;
12449     }
12450   aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
12451 }
12452
12453 static void
12454 dexDataProc1Source (sim_cpu *cpu)
12455 {
12456   /* instr[30]    = 1
12457      instr[28,21] = 111010110
12458      instr[31]    = size : 0 ==> 32 bit, 1 ==> 64 bit
12459      instr[29]    = S : 0 ==> ok, 1 ==> UNALLOC
12460      instr[20,16] = opcode2 : 00000 ==> ok, ow ==> UNALLOC
12461      instr[15,10] = opcode : 000000 ==> RBIT, 000001 ==> REV16,
12462                              000010 ==> REV, 000011 ==> UNALLOC
12463                              000100 ==> CLZ, 000101 ==> CLS
12464                              ow ==> UNALLOC
12465      instr[9,5]   = rn : may not be SP
12466      instr[4,0]   = rd : may not be SP.  */
12467
12468   uint32_t S = INSTR (29, 29);
12469   uint32_t opcode2 = INSTR (20, 16);
12470   uint32_t opcode = INSTR (15, 10);
12471   uint32_t dispatch = ((INSTR (31, 31) << 3) | opcode);
12472
12473   if (S == 1)
12474     HALT_UNALLOC;
12475
12476   if (opcode2 != 0)
12477     HALT_UNALLOC;
12478
12479   if (opcode & 0x38)
12480     HALT_UNALLOC;
12481
12482   switch (dispatch)
12483     {
12484     case 0: rbit32 (cpu); return;
12485     case 1: revh32 (cpu); return;
12486     case 2: rev32 (cpu); return;
12487     case 4: clz32 (cpu); return;
12488     case 5: cls32 (cpu); return;
12489     case 8: rbit64 (cpu); return;
12490     case 9: revh64 (cpu); return;
12491     case 10:rev32 (cpu); return;
12492     case 11:rev64 (cpu); return;
12493     case 12:clz64 (cpu); return;
12494     case 13:cls64 (cpu); return;
12495     default: HALT_UNALLOC;
12496     }
12497 }
12498
12499 /* Variable shift.
12500    Shifts by count supplied in register.
12501    N.B register args may not be SP.
12502    These all use the shifted auxiliary function for
12503    simplicity and clarity.  Writing the actual shift
12504    inline would avoid a branch and so be faster but
12505    would also necessitate getting signs right.  */
12506
12507 /* 32 bit arithmetic shift right.  */
12508 static void
12509 asrv32 (sim_cpu *cpu)
12510 {
12511   unsigned rm = INSTR (20, 16);
12512   unsigned rn = INSTR (9, 5);
12513   unsigned rd = INSTR (4, 0);
12514
12515   aarch64_set_reg_u64
12516     (cpu, rd, NO_SP,
12517      shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), ASR,
12518                 (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f)));
12519 }
12520
12521 /* 64 bit arithmetic shift right.  */
12522 static void
12523 asrv64 (sim_cpu *cpu)
12524 {
12525   unsigned rm = INSTR (20, 16);
12526   unsigned rn = INSTR (9, 5);
12527   unsigned rd = INSTR (4, 0);
12528
12529   aarch64_set_reg_u64
12530     (cpu, rd, NO_SP,
12531      shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), ASR,
12532                 (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f)));
12533 }
12534
12535 /* 32 bit logical shift left.  */
12536 static void
12537 lslv32 (sim_cpu *cpu)
12538 {
12539   unsigned rm = INSTR (20, 16);
12540   unsigned rn = INSTR (9, 5);
12541   unsigned rd = INSTR (4, 0);
12542
12543   aarch64_set_reg_u64
12544     (cpu, rd, NO_SP,
12545      shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), LSL,
12546                 (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f)));
12547 }
12548
12549 /* 64 bit arithmetic shift left.  */
12550 static void
12551 lslv64 (sim_cpu *cpu)
12552 {
12553   unsigned rm = INSTR (20, 16);
12554   unsigned rn = INSTR (9, 5);
12555   unsigned rd = INSTR (4, 0);
12556
12557   aarch64_set_reg_u64
12558     (cpu, rd, NO_SP,
12559      shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), LSL,
12560                 (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f)));
12561 }
12562
12563 /* 32 bit logical shift right.  */
12564 static void
12565 lsrv32 (sim_cpu *cpu)
12566 {
12567   unsigned rm = INSTR (20, 16);
12568   unsigned rn = INSTR (9, 5);
12569   unsigned rd = INSTR (4, 0);
12570
12571   aarch64_set_reg_u64
12572     (cpu, rd, NO_SP,
12573      shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), LSR,
12574                 (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f)));
12575 }
12576
12577 /* 64 bit logical shift right.  */
12578 static void
12579 lsrv64 (sim_cpu *cpu)
12580 {
12581   unsigned rm = INSTR (20, 16);
12582   unsigned rn = INSTR (9, 5);
12583   unsigned rd = INSTR (4, 0);
12584
12585   aarch64_set_reg_u64
12586     (cpu, rd, NO_SP,
12587      shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), LSR,
12588                 (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f)));
12589 }
12590
12591 /* 32 bit rotate right.  */
12592 static void
12593 rorv32 (sim_cpu *cpu)
12594 {
12595   unsigned rm = INSTR (20, 16);
12596   unsigned rn = INSTR (9, 5);
12597   unsigned rd = INSTR (4, 0);
12598
12599   aarch64_set_reg_u64
12600     (cpu, rd, NO_SP,
12601      shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), ROR,
12602                 (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f)));
12603 }
12604
12605 /* 64 bit rotate right.  */
12606 static void
12607 rorv64 (sim_cpu *cpu)
12608 {
12609   unsigned rm = INSTR (20, 16);
12610   unsigned rn = INSTR (9, 5);
12611   unsigned rd = INSTR (4, 0);
12612
12613   aarch64_set_reg_u64
12614     (cpu, rd, NO_SP,
12615      shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), ROR,
12616                 (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f)));
12617 }
12618
12619
12620 /* divide.  */
12621
12622 /* 32 bit signed divide.  */
12623 static void
12624 cpuiv32 (sim_cpu *cpu)
12625 {
12626   unsigned rm = INSTR (20, 16);
12627   unsigned rn = INSTR (9, 5);
12628   unsigned rd = INSTR (4, 0);
12629   /* N.B. the pseudo-code does the divide using 64 bit data.  */
12630   /* TODO : check that this rounds towards zero as required.  */
12631   int64_t dividend = aarch64_get_reg_s32 (cpu, rn, NO_SP);
12632   int64_t divisor = aarch64_get_reg_s32 (cpu, rm, NO_SP);
12633
12634   aarch64_set_reg_s64 (cpu, rd, NO_SP,
12635                        divisor ? ((int32_t) (dividend / divisor)) : 0);
12636 }
12637
12638 /* 64 bit signed divide.  */
12639 static void
12640 cpuiv64 (sim_cpu *cpu)
12641 {
12642   unsigned rm = INSTR (20, 16);
12643   unsigned rn = INSTR (9, 5);
12644   unsigned rd = INSTR (4, 0);
12645
12646   /* TODO : check that this rounds towards zero as required.  */
12647   int64_t divisor = aarch64_get_reg_s64 (cpu, rm, NO_SP);
12648
12649   aarch64_set_reg_s64
12650     (cpu, rd, NO_SP,
12651      divisor ? (aarch64_get_reg_s64 (cpu, rn, NO_SP) / divisor) : 0);
12652 }
12653
12654 /* 32 bit unsigned divide.  */
12655 static void
12656 udiv32 (sim_cpu *cpu)
12657 {
12658   unsigned rm = INSTR (20, 16);
12659   unsigned rn = INSTR (9, 5);
12660   unsigned rd = INSTR (4, 0);
12661
12662   /* N.B. the pseudo-code does the divide using 64 bit data.  */
12663   uint64_t dividend = aarch64_get_reg_u32 (cpu, rn, NO_SP);
12664   uint64_t divisor  = aarch64_get_reg_u32 (cpu, rm, NO_SP);
12665
12666   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12667                        divisor ? (uint32_t) (dividend / divisor) : 0);
12668 }
12669
12670 /* 64 bit unsigned divide.  */
12671 static void
12672 udiv64 (sim_cpu *cpu)
12673 {
12674   unsigned rm = INSTR (20, 16);
12675   unsigned rn = INSTR (9, 5);
12676   unsigned rd = INSTR (4, 0);
12677
12678   /* TODO : check that this rounds towards zero as required.  */
12679   uint64_t divisor = aarch64_get_reg_u64 (cpu, rm, NO_SP);
12680
12681   aarch64_set_reg_u64
12682     (cpu, rd, NO_SP,
12683      divisor ? (aarch64_get_reg_u64 (cpu, rn, NO_SP) / divisor) : 0);
12684 }
12685
12686 static void
12687 dexDataProc2Source (sim_cpu *cpu)
12688 {
12689   /* assert instr[30] == 0
12690      instr[28,21] == 11010110
12691      instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
12692      instr[29] = S : 0 ==> ok, 1 ==> UNALLOC
12693      instr[15,10] = opcode : 000010 ==> UDIV, 000011 ==> CPUIV,
12694                              001000 ==> LSLV, 001001 ==> LSRV
12695                              001010 ==> ASRV, 001011 ==> RORV
12696                              ow ==> UNALLOC.  */
12697
12698   uint32_t dispatch;
12699   uint32_t S = INSTR (29, 29);
12700   uint32_t opcode = INSTR (15, 10);
12701
12702   if (S == 1)
12703     HALT_UNALLOC;
12704
12705   if (opcode & 0x34)
12706     HALT_UNALLOC;
12707
12708   dispatch = (  (INSTR (31, 31) << 3)
12709               | (uimm (opcode, 3, 3) << 2)
12710               |  uimm (opcode, 1, 0));
12711   switch (dispatch)
12712     {
12713     case 2:  udiv32 (cpu); return;
12714     case 3:  cpuiv32 (cpu); return;
12715     case 4:  lslv32 (cpu); return;
12716     case 5:  lsrv32 (cpu); return;
12717     case 6:  asrv32 (cpu); return;
12718     case 7:  rorv32 (cpu); return;
12719     case 10: udiv64 (cpu); return;
12720     case 11: cpuiv64 (cpu); return;
12721     case 12: lslv64 (cpu); return;
12722     case 13: lsrv64 (cpu); return;
12723     case 14: asrv64 (cpu); return;
12724     case 15: rorv64 (cpu); return;
12725     default: HALT_UNALLOC;
12726     }
12727 }
12728
12729
12730 /* Multiply.  */
12731
12732 /* 32 bit multiply and add.  */
12733 static void
12734 madd32 (sim_cpu *cpu)
12735 {
12736   unsigned rm = INSTR (20, 16);
12737   unsigned ra = INSTR (14, 10);
12738   unsigned rn = INSTR (9, 5);
12739   unsigned rd = INSTR (4, 0);
12740
12741   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
12742   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12743                        aarch64_get_reg_u32 (cpu, ra, NO_SP)
12744                        + aarch64_get_reg_u32 (cpu, rn, NO_SP)
12745                        * aarch64_get_reg_u32 (cpu, rm, NO_SP));
12746 }
12747
12748 /* 64 bit multiply and add.  */
12749 static void
12750 madd64 (sim_cpu *cpu)
12751 {
12752   unsigned rm = INSTR (20, 16);
12753   unsigned ra = INSTR (14, 10);
12754   unsigned rn = INSTR (9, 5);
12755   unsigned rd = INSTR (4, 0);
12756
12757   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
12758   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12759                        aarch64_get_reg_u64 (cpu, ra, NO_SP)
12760                        + (aarch64_get_reg_u64 (cpu, rn, NO_SP)
12761                           * aarch64_get_reg_u64 (cpu, rm, NO_SP)));
12762 }
12763
12764 /* 32 bit multiply and sub.  */
12765 static void
12766 msub32 (sim_cpu *cpu)
12767 {
12768   unsigned rm = INSTR (20, 16);
12769   unsigned ra = INSTR (14, 10);
12770   unsigned rn = INSTR (9, 5);
12771   unsigned rd = INSTR (4, 0);
12772
12773   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
12774   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12775                        aarch64_get_reg_u32 (cpu, ra, NO_SP)
12776                        - aarch64_get_reg_u32 (cpu, rn, NO_SP)
12777                        * aarch64_get_reg_u32 (cpu, rm, NO_SP));
12778 }
12779
12780 /* 64 bit multiply and sub.  */
12781 static void
12782 msub64 (sim_cpu *cpu)
12783 {
12784   unsigned rm = INSTR (20, 16);
12785   unsigned ra = INSTR (14, 10);
12786   unsigned rn = INSTR (9, 5);
12787   unsigned rd = INSTR (4, 0);
12788
12789   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
12790   aarch64_set_reg_u64 (cpu, rd, NO_SP,
12791                        aarch64_get_reg_u64 (cpu, ra, NO_SP)
12792                        - aarch64_get_reg_u64 (cpu, rn, NO_SP)
12793                        * aarch64_get_reg_u64 (cpu, rm, NO_SP));
12794 }
12795
12796 /* Signed multiply add long -- source, source2 : 32 bit, source3 : 64 bit.  */
12797 static void
12798 smaddl (sim_cpu *cpu)
12799 {
12800   unsigned rm = INSTR (20, 16);
12801   unsigned ra = INSTR (14, 10);
12802   unsigned rn = INSTR (9, 5);
12803   unsigned rd = INSTR (4, 0);
12804
12805   /* N.B. we need to multiply the signed 32 bit values in rn, rm to
12806      obtain a 64 bit product.  */
12807   aarch64_set_reg_s64
12808     (cpu, rd, NO_SP,
12809      aarch64_get_reg_s64 (cpu, ra, NO_SP)
12810      + ((int64_t) aarch64_get_reg_s32 (cpu, rn, NO_SP))
12811      * ((int64_t) aarch64_get_reg_s32 (cpu, rm, NO_SP)));
12812 }
12813
12814 /* Signed multiply sub long -- source, source2 : 32 bit, source3 : 64 bit.  */
12815 static void
12816 smsubl (sim_cpu *cpu)
12817 {
12818   unsigned rm = INSTR (20, 16);
12819   unsigned ra = INSTR (14, 10);
12820   unsigned rn = INSTR (9, 5);
12821   unsigned rd = INSTR (4, 0);
12822
12823   /* N.B. we need to multiply the signed 32 bit values in rn, rm to
12824      obtain a 64 bit product.  */
12825   aarch64_set_reg_s64
12826     (cpu, rd, NO_SP,
12827      aarch64_get_reg_s64 (cpu, ra, NO_SP)
12828      - ((int64_t) aarch64_get_reg_s32 (cpu, rn, NO_SP))
12829      * ((int64_t) aarch64_get_reg_s32 (cpu, rm, NO_SP)));
12830 }
12831
12832 /* Integer Multiply/Divide.  */
12833
12834 /* First some macros and a helper function.  */
12835 /* Macros to test or access elements of 64 bit words.  */
12836
12837 /* Mask used to access lo 32 bits of 64 bit unsigned int.  */
12838 #define LOW_WORD_MASK ((1ULL << 32) - 1)
12839 /* Return the lo 32 bit word of a 64 bit unsigned int as a 64 bit unsigned int.  */
12840 #define lowWordToU64(_value_u64) ((_value_u64) & LOW_WORD_MASK)
12841 /* Return the hi 32 bit word of a 64 bit unsigned int as a 64 bit unsigned int.  */
12842 #define highWordToU64(_value_u64) ((_value_u64) >> 32)
12843
12844 /* Offset of sign bit in 64 bit signed integger.  */
12845 #define SIGN_SHIFT_U64 63
12846 /* The sign bit itself -- also identifies the minimum negative int value.  */
12847 #define SIGN_BIT_U64 (1UL << SIGN_SHIFT_U64)
12848 /* Return true if a 64 bit signed int presented as an unsigned int is the
12849    most negative value.  */
12850 #define isMinimumU64(_value_u64) ((_value_u64) == SIGN_BIT_U64)
12851 /* Return true (non-zero) if a 64 bit signed int presented as an unsigned
12852    int has its sign bit set to false.  */
12853 #define isSignSetU64(_value_u64) ((_value_u64) & SIGN_BIT_U64)
12854 /* Return 1L or -1L according to whether a 64 bit signed int presented as
12855    an unsigned int has its sign bit set or not.  */
12856 #define signOfU64(_value_u64) (1L + (((value_u64) >> SIGN_SHIFT_U64) * -2L)
12857 /* Clear the sign bit of a 64 bit signed int presented as an unsigned int.  */
12858 #define clearSignU64(_value_u64) ((_value_u64) &= ~SIGN_BIT_U64)
12859
12860 /* Multiply two 64 bit ints and return.
12861    the hi 64 bits of the 128 bit product.  */
12862
12863 static uint64_t
12864 mul64hi (uint64_t value1, uint64_t value2)
12865 {
12866   uint64_t resultmid1;
12867   uint64_t result;
12868   uint64_t value1_lo = lowWordToU64 (value1);
12869   uint64_t value1_hi = highWordToU64 (value1) ;
12870   uint64_t value2_lo = lowWordToU64 (value2);
12871   uint64_t value2_hi = highWordToU64 (value2);
12872
12873   /* Cross-multiply and collect results.  */
12874   uint64_t xproductlo = value1_lo * value2_lo;
12875   uint64_t xproductmid1 = value1_lo * value2_hi;
12876   uint64_t xproductmid2 = value1_hi * value2_lo;
12877   uint64_t xproducthi = value1_hi * value2_hi;
12878   uint64_t carry = 0;
12879   /* Start accumulating 64 bit results.  */
12880   /* Drop bottom half of lowest cross-product.  */
12881   uint64_t resultmid = xproductlo >> 32;
12882   /* Add in middle products.  */
12883   resultmid = resultmid + xproductmid1;
12884
12885   /* Check for overflow.  */
12886   if (resultmid < xproductmid1)
12887     /* Carry over 1 into top cross-product.  */
12888     carry++;
12889
12890   resultmid1  = resultmid + xproductmid2;
12891
12892   /* Check for overflow.  */
12893   if (resultmid1 < xproductmid2)
12894     /* Carry over 1 into top cross-product.  */
12895     carry++;
12896
12897   /* Drop lowest 32 bits of middle cross-product.  */
12898   result = resultmid1 >> 32;
12899
12900   /* Add top cross-product plus and any carry.  */
12901   result += xproducthi + carry;
12902
12903   return result;
12904 }
12905
12906 /* Signed multiply high, source, source2 :
12907    64 bit, dest <-- high 64-bit of result.  */
12908 static void
12909 smulh (sim_cpu *cpu)
12910 {
12911   uint64_t uresult;
12912   int64_t  result;
12913   unsigned rm = INSTR (20, 16);
12914   unsigned rn = INSTR (9, 5);
12915   unsigned rd = INSTR (4, 0);
12916   GReg     ra = INSTR (14, 10);
12917   int64_t  value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP);
12918   int64_t  value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP);
12919   uint64_t uvalue1;
12920   uint64_t uvalue2;
12921   int64_t  signum = 1;
12922
12923   if (ra != R31)
12924     HALT_UNALLOC;
12925
12926   /* Convert to unsigned and use the unsigned mul64hi routine
12927      the fix the sign up afterwards.  */
12928   if (value1 < 0)
12929     {
12930       signum *= -1L;
12931       uvalue1 = -value1;
12932     }
12933   else
12934     {
12935       uvalue1 = value1;
12936     }
12937
12938   if (value2 < 0)
12939     {
12940       signum *= -1L;
12941       uvalue2 = -value2;
12942     }
12943   else
12944     {
12945       uvalue2 = value2;
12946     }
12947
12948   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
12949   uresult = mul64hi (uvalue1, uvalue2);
12950   result = uresult;
12951   result *= signum;
12952
12953   aarch64_set_reg_s64 (cpu, rd, NO_SP, result);
12954 }
12955
12956 /* Unsigned multiply add long -- source, source2 :
12957    32 bit, source3 : 64 bit.  */
12958 static void
12959 umaddl (sim_cpu *cpu)
12960 {
12961   unsigned rm = INSTR (20, 16);
12962   unsigned ra = INSTR (14, 10);
12963   unsigned rn = INSTR (9, 5);
12964   unsigned rd = INSTR (4, 0);
12965
12966   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
12967   /* N.B. we need to multiply the signed 32 bit values in rn, rm to
12968      obtain a 64 bit product.  */
12969   aarch64_set_reg_u64
12970     (cpu, rd, NO_SP,
12971      aarch64_get_reg_u64 (cpu, ra, NO_SP)
12972      + ((uint64_t) aarch64_get_reg_u32 (cpu, rn, NO_SP))
12973      * ((uint64_t) aarch64_get_reg_u32 (cpu, rm, NO_SP)));
12974 }
12975
12976 /* Unsigned multiply sub long -- source, source2 : 32 bit, source3 : 64 bit.  */
12977 static void
12978 umsubl (sim_cpu *cpu)
12979 {
12980   unsigned rm = INSTR (20, 16);
12981   unsigned ra = INSTR (14, 10);
12982   unsigned rn = INSTR (9, 5);
12983   unsigned rd = INSTR (4, 0);
12984
12985   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
12986   /* N.B. we need to multiply the signed 32 bit values in rn, rm to
12987      obtain a 64 bit product.  */
12988   aarch64_set_reg_u64
12989     (cpu, rd, NO_SP,
12990      aarch64_get_reg_u64 (cpu, ra, NO_SP)
12991      - ((uint64_t) aarch64_get_reg_u32 (cpu, rn, NO_SP))
12992      * ((uint64_t) aarch64_get_reg_u32 (cpu, rm, NO_SP)));
12993 }
12994
12995 /* Unsigned multiply high, source, source2 :
12996    64 bit, dest <-- high 64-bit of result.  */
12997 static void
12998 umulh (sim_cpu *cpu)
12999 {
13000   unsigned rm = INSTR (20, 16);
13001   unsigned rn = INSTR (9, 5);
13002   unsigned rd = INSTR (4, 0);
13003   GReg     ra = INSTR (14, 10);
13004
13005   if (ra != R31)
13006     HALT_UNALLOC;
13007
13008   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13009   aarch64_set_reg_u64 (cpu, rd, NO_SP,
13010                        mul64hi (aarch64_get_reg_u64 (cpu, rn, NO_SP),
13011                                 aarch64_get_reg_u64 (cpu, rm, NO_SP)));
13012 }
13013
13014 static void
13015 dexDataProc3Source (sim_cpu *cpu)
13016 {
13017   /* assert instr[28,24] == 11011.  */
13018   /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit (for rd at least)
13019      instr[30,29] = op54 : 00 ==> ok, ow ==> UNALLOC
13020      instr[23,21] = op31 : 111 ==> UNALLOC, o2 ==> ok
13021      instr[15] = o0 : 0/1 ==> ok
13022      instr[23,21:15] ==> op : 0000 ==> MADD, 0001 ==> MSUB,     (32/64 bit)
13023                               0010 ==> SMADDL, 0011 ==> SMSUBL, (64 bit only)
13024                               0100 ==> SMULH,                   (64 bit only)
13025                               1010 ==> UMADDL, 1011 ==> UNSUBL, (64 bit only)
13026                               1100 ==> UMULH                    (64 bit only)
13027                               ow ==> UNALLOC.  */
13028
13029   uint32_t dispatch;
13030   uint32_t size = INSTR (31, 31);
13031   uint32_t op54 = INSTR (30, 29);
13032   uint32_t op31 = INSTR (23, 21);
13033   uint32_t o0 = INSTR (15, 15);
13034
13035   if (op54 != 0)
13036     HALT_UNALLOC;
13037
13038   if (size == 0)
13039     {
13040       if (op31 != 0)
13041         HALT_UNALLOC;
13042
13043       if (o0 == 0)
13044         madd32 (cpu);
13045       else
13046         msub32 (cpu);
13047       return;
13048     }
13049
13050   dispatch = (op31 << 1) | o0;
13051
13052   switch (dispatch)
13053     {
13054     case 0:  madd64 (cpu); return;
13055     case 1:  msub64 (cpu); return;
13056     case 2:  smaddl (cpu); return;
13057     case 3:  smsubl (cpu); return;
13058     case 4:  smulh (cpu); return;
13059     case 10: umaddl (cpu); return;
13060     case 11: umsubl (cpu); return;
13061     case 12: umulh (cpu); return;
13062     default: HALT_UNALLOC;
13063     }
13064 }
13065
13066 static void
13067 dexDPReg (sim_cpu *cpu)
13068 {
13069   /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu));
13070      assert  group == GROUP_DPREG_0101 || group == GROUP_DPREG_1101
13071      bits [28:24:21] of a DPReg are the secondary dispatch vector.  */
13072   uint32_t group2 = dispatchDPReg (aarch64_get_instr (cpu));
13073
13074   switch (group2)
13075     {
13076     case DPREG_LOG_000:
13077     case DPREG_LOG_001:
13078       dexLogicalShiftedRegister (cpu); return;
13079
13080     case DPREG_ADDSHF_010:
13081       dexAddSubtractShiftedRegister (cpu); return;
13082
13083     case DPREG_ADDEXT_011:
13084       dexAddSubtractExtendedRegister (cpu); return;
13085
13086     case DPREG_ADDCOND_100:
13087       {
13088         /* This set bundles a variety of different operations.  */
13089         /* Check for.  */
13090         /* 1) add/sub w carry.  */
13091         uint32_t mask1 = 0x1FE00000U;
13092         uint32_t val1  = 0x1A000000U;
13093         /* 2) cond compare register/immediate.  */
13094         uint32_t mask2 = 0x1FE00000U;
13095         uint32_t val2  = 0x1A400000U;
13096         /* 3) cond select.  */
13097         uint32_t mask3 = 0x1FE00000U;
13098         uint32_t val3  = 0x1A800000U;
13099         /* 4) data proc 1/2 source.  */
13100         uint32_t mask4 = 0x1FE00000U;
13101         uint32_t val4  = 0x1AC00000U;
13102
13103         if ((aarch64_get_instr (cpu) & mask1) == val1)
13104           dexAddSubtractWithCarry (cpu);
13105
13106         else if ((aarch64_get_instr (cpu) & mask2) == val2)
13107           CondCompare (cpu);
13108
13109         else if ((aarch64_get_instr (cpu) & mask3) == val3)
13110           dexCondSelect (cpu);
13111
13112         else if ((aarch64_get_instr (cpu) & mask4) == val4)
13113           {
13114             /* Bit 30 is clear for data proc 2 source
13115                and set for data proc 1 source.  */
13116             if (aarch64_get_instr (cpu)  & (1U << 30))
13117               dexDataProc1Source (cpu);
13118             else
13119               dexDataProc2Source (cpu);
13120           }
13121
13122         else
13123           /* Should not reach here.  */
13124           HALT_NYI;
13125
13126         return;
13127       }
13128
13129     case DPREG_3SRC_110:
13130       dexDataProc3Source (cpu); return;
13131
13132     case DPREG_UNALLOC_101:
13133       HALT_UNALLOC;
13134
13135     case DPREG_3SRC_111:
13136       dexDataProc3Source (cpu); return;
13137
13138     default:
13139       /* Should never reach here.  */
13140       HALT_NYI;
13141     }
13142 }
13143
13144 /* Unconditional Branch immediate.
13145    Offset is a PC-relative byte offset in the range +/- 128MiB.
13146    The offset is assumed to be raw from the decode i.e. the
13147    simulator is expected to scale them from word offsets to byte.  */
13148
13149 /* Unconditional branch.  */
13150 static void
13151 buc (sim_cpu *cpu, int32_t offset)
13152 {
13153   aarch64_set_next_PC_by_offset (cpu, offset);
13154 }
13155
13156 static unsigned stack_depth = 0;
13157
13158 /* Unconditional branch and link -- writes return PC to LR.  */
13159 static void
13160 bl (sim_cpu *cpu, int32_t offset)
13161 {
13162   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13163   aarch64_save_LR (cpu);
13164   aarch64_set_next_PC_by_offset (cpu, offset);
13165
13166   if (TRACE_BRANCH_P (cpu))
13167     {
13168       ++ stack_depth;
13169       TRACE_BRANCH (cpu,
13170                     " %*scall %" PRIx64 " [%s]"
13171                     " [args: %" PRIx64 " %" PRIx64 " %" PRIx64 "]",
13172                     stack_depth, " ", aarch64_get_next_PC (cpu),
13173                     aarch64_get_func (CPU_STATE (cpu),
13174                                       aarch64_get_next_PC (cpu)),
13175                     aarch64_get_reg_u64 (cpu, 0, NO_SP),
13176                     aarch64_get_reg_u64 (cpu, 1, NO_SP),
13177                     aarch64_get_reg_u64 (cpu, 2, NO_SP)
13178                     );
13179     }
13180 }
13181
13182 /* Unconditional Branch register.
13183    Branch/return address is in source register.  */
13184
13185 /* Unconditional branch.  */
13186 static void
13187 br (sim_cpu *cpu)
13188 {
13189   unsigned rn = INSTR (9, 5);
13190   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13191   aarch64_set_next_PC (cpu, aarch64_get_reg_u64 (cpu, rn, NO_SP));
13192 }
13193
13194 /* Unconditional branch and link -- writes return PC to LR.  */
13195 static void
13196 blr (sim_cpu *cpu)
13197 {
13198   unsigned rn = INSTR (9, 5);
13199
13200   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13201   /* The pseudo code in the spec says we update LR before fetching.
13202      the value from the rn.  */
13203   aarch64_save_LR (cpu);
13204   aarch64_set_next_PC (cpu, aarch64_get_reg_u64 (cpu, rn, NO_SP));
13205
13206   if (TRACE_BRANCH_P (cpu))
13207     {
13208       ++ stack_depth;
13209       TRACE_BRANCH (cpu,
13210                     " %*scall %" PRIx64 " [%s]"
13211                     " [args: %" PRIx64 " %" PRIx64 " %" PRIx64 "]",
13212                     stack_depth, " ", aarch64_get_next_PC (cpu),
13213                     aarch64_get_func (CPU_STATE (cpu),
13214                                       aarch64_get_next_PC (cpu)),
13215                     aarch64_get_reg_u64 (cpu, 0, NO_SP),
13216                     aarch64_get_reg_u64 (cpu, 1, NO_SP),
13217                     aarch64_get_reg_u64 (cpu, 2, NO_SP)
13218                     );
13219     }
13220 }
13221
13222 /* Return -- assembler will default source to LR this is functionally
13223    equivalent to br but, presumably, unlike br it side effects the
13224    branch predictor.  */
13225 static void
13226 ret (sim_cpu *cpu)
13227 {
13228   unsigned rn = INSTR (9, 5);
13229   aarch64_set_next_PC (cpu, aarch64_get_reg_u64 (cpu, rn, NO_SP));
13230
13231   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13232   if (TRACE_BRANCH_P (cpu))
13233     {
13234       TRACE_BRANCH (cpu,
13235                     " %*sreturn [result: %" PRIx64 "]",
13236                     stack_depth, " ", aarch64_get_reg_u64 (cpu, 0, NO_SP));
13237       -- stack_depth;
13238     }
13239 }
13240
13241 /* NOP -- we implement this and call it from the decode in case we
13242    want to intercept it later.  */
13243
13244 static void
13245 nop (sim_cpu *cpu)
13246 {
13247   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13248 }
13249
13250 /* Data synchronization barrier.  */
13251
13252 static void
13253 dsb (sim_cpu *cpu)
13254 {
13255   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13256 }
13257
13258 /* Data memory barrier.  */
13259
13260 static void
13261 dmb (sim_cpu *cpu)
13262 {
13263   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13264 }
13265
13266 /* Instruction synchronization barrier.  */
13267
13268 static void
13269 isb (sim_cpu *cpu)
13270 {
13271   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13272 }
13273
13274 static void
13275 dexBranchImmediate (sim_cpu *cpu)
13276 {
13277   /* assert instr[30,26] == 00101
13278      instr[31] ==> 0 == B, 1 == BL
13279      instr[25,0] == imm26 branch offset counted in words.  */
13280
13281   uint32_t top = INSTR (31, 31);
13282   /* We have a 26 byte signed word offset which we need to pass to the
13283      execute routine as a signed byte offset.  */
13284   int32_t offset = simm32 (aarch64_get_instr (cpu), 25, 0) << 2;
13285
13286   if (top)
13287     bl (cpu, offset);
13288   else
13289     buc (cpu, offset);
13290 }
13291
13292 /* Control Flow.  */
13293
13294 /* Conditional branch
13295
13296    Offset is a PC-relative byte offset in the range +/- 1MiB pos is
13297    a bit position in the range 0 .. 63
13298
13299    cc is a CondCode enum value as pulled out of the decode
13300
13301    N.B. any offset register (source) can only be Xn or Wn.  */
13302
13303 static void
13304 bcc (sim_cpu *cpu, int32_t offset, CondCode cc)
13305 {
13306   /* The test returns TRUE if CC is met.  */
13307   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13308   if (testConditionCode (cpu, cc))
13309     aarch64_set_next_PC_by_offset (cpu, offset);
13310 }
13311
13312 /* 32 bit branch on register non-zero.  */
13313 static void
13314 cbnz32 (sim_cpu *cpu, int32_t offset)
13315 {
13316   unsigned rt = INSTR (4, 0);
13317
13318   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13319   if (aarch64_get_reg_u32 (cpu, rt, NO_SP) != 0)
13320     aarch64_set_next_PC_by_offset (cpu, offset);
13321 }
13322
13323 /* 64 bit branch on register zero.  */
13324 static void
13325 cbnz (sim_cpu *cpu, int32_t offset)
13326 {
13327   unsigned rt = INSTR (4, 0);
13328
13329   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13330   if (aarch64_get_reg_u64 (cpu, rt, NO_SP) != 0)
13331     aarch64_set_next_PC_by_offset (cpu, offset);
13332 }
13333
13334 /* 32 bit branch on register non-zero.  */
13335 static void
13336 cbz32 (sim_cpu *cpu, int32_t offset)
13337 {
13338   unsigned rt = INSTR (4, 0);
13339
13340   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13341   if (aarch64_get_reg_u32 (cpu, rt, NO_SP) == 0)
13342     aarch64_set_next_PC_by_offset (cpu, offset);
13343 }
13344
13345 /* 64 bit branch on register zero.  */
13346 static void
13347 cbz (sim_cpu *cpu, int32_t offset)
13348 {
13349   unsigned rt = INSTR (4, 0);
13350
13351   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13352   if (aarch64_get_reg_u64 (cpu, rt, NO_SP) == 0)
13353     aarch64_set_next_PC_by_offset (cpu, offset);
13354 }
13355
13356 /* Branch on register bit test non-zero -- one size fits all.  */
13357 static void
13358 tbnz (sim_cpu *cpu, uint32_t  pos, int32_t offset)
13359 {
13360   unsigned rt = INSTR (4, 0);
13361
13362   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13363   if (aarch64_get_reg_u64 (cpu, rt, NO_SP) & (((uint64_t) 1) << pos))
13364     aarch64_set_next_PC_by_offset (cpu, offset);
13365 }
13366
13367 /* Branch on register bit test zero -- one size fits all.  */
13368 static void
13369 tbz (sim_cpu *cpu, uint32_t  pos, int32_t offset)
13370 {
13371   unsigned rt = INSTR (4, 0);
13372
13373   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13374   if (!(aarch64_get_reg_u64 (cpu, rt, NO_SP) & (((uint64_t) 1) << pos)))
13375     aarch64_set_next_PC_by_offset (cpu, offset);
13376 }
13377
13378 static void
13379 dexCompareBranchImmediate (sim_cpu *cpu)
13380 {
13381   /* instr[30,25] = 01 1010
13382      instr[31]    = size : 0 ==> 32, 1 ==> 64
13383      instr[24]    = op : 0 ==> CBZ, 1 ==> CBNZ
13384      instr[23,5]  = simm19 branch offset counted in words
13385      instr[4,0]   = rt  */
13386
13387   uint32_t size = INSTR (31, 31);
13388   uint32_t op   = INSTR (24, 24);
13389   int32_t offset = simm32 (aarch64_get_instr (cpu), 23, 5) << 2;
13390
13391   if (size == 0)
13392     {
13393       if (op == 0)
13394         cbz32 (cpu, offset);
13395       else
13396         cbnz32 (cpu, offset);
13397     }
13398   else
13399     {
13400       if (op == 0)
13401         cbz (cpu, offset);
13402       else
13403         cbnz (cpu, offset);
13404     }
13405 }
13406
13407 static void
13408 dexTestBranchImmediate (sim_cpu *cpu)
13409 {
13410   /* instr[31]    = b5 : bit 5 of test bit idx
13411      instr[30,25] = 01 1011
13412      instr[24]    = op : 0 ==> TBZ, 1 == TBNZ
13413      instr[23,19] = b40 : bits 4 to 0 of test bit idx
13414      instr[18,5]  = simm14 : signed offset counted in words
13415      instr[4,0]   = uimm5  */
13416
13417   uint32_t pos = ((INSTR (31, 31) << 5) | INSTR (23, 19));
13418   int32_t offset = simm32 (aarch64_get_instr (cpu), 18, 5) << 2;
13419
13420   NYI_assert (30, 25, 0x1b);
13421
13422   if (INSTR (24, 24) == 0)
13423     tbz (cpu, pos, offset);
13424   else
13425     tbnz (cpu, pos, offset);
13426 }
13427
13428 static void
13429 dexCondBranchImmediate (sim_cpu *cpu)
13430 {
13431   /* instr[31,25] = 010 1010
13432      instr[24]    = op1; op => 00 ==> B.cond
13433      instr[23,5]  = simm19 : signed offset counted in words
13434      instr[4]     = op0
13435      instr[3,0]   = cond  */
13436
13437   int32_t offset;
13438   uint32_t op = ((INSTR (24, 24) << 1) | INSTR (4, 4));
13439
13440   NYI_assert (31, 25, 0x2a);
13441
13442   if (op != 0)
13443     HALT_UNALLOC;
13444
13445   offset = simm32 (aarch64_get_instr (cpu), 23, 5) << 2;
13446
13447   bcc (cpu, offset, INSTR (3, 0));
13448 }
13449
13450 static void
13451 dexBranchRegister (sim_cpu *cpu)
13452 {
13453   /* instr[31,25] = 110 1011
13454      instr[24,21] = op : 0 ==> BR, 1 => BLR, 2 => RET, 3 => ERET, 4 => DRPS
13455      instr[20,16] = op2 : must be 11111
13456      instr[15,10] = op3 : must be 000000
13457      instr[4,0]   = op2 : must be 11111.  */
13458
13459   uint32_t op = INSTR (24, 21);
13460   uint32_t op2 = INSTR (20, 16);
13461   uint32_t op3 = INSTR (15, 10);
13462   uint32_t op4 = INSTR (4, 0);
13463
13464   NYI_assert (31, 25, 0x6b);
13465
13466   if (op2 != 0x1F || op3 != 0 || op4 != 0)
13467     HALT_UNALLOC;
13468
13469   if (op == 0)
13470     br (cpu);
13471
13472   else if (op == 1)
13473     blr (cpu);
13474
13475   else if (op == 2)
13476     ret (cpu);
13477
13478   else
13479     {
13480       /* ERET and DRPS accept 0b11111 for rn = instr [4,0].  */
13481       /* anything else is unallocated.  */
13482       uint32_t rn = INSTR (4, 0);
13483
13484       if (rn != 0x1f)
13485         HALT_UNALLOC;
13486
13487       if (op == 4 || op == 5)
13488         HALT_NYI;
13489
13490       HALT_UNALLOC;
13491     }
13492 }
13493
13494 /* FIXME: We should get the Angel SWI values from ../../libgloss/aarch64/svc.h
13495    but this may not be available.  So instead we define the values we need
13496    here.  */
13497 #define AngelSVC_Reason_Open            0x01
13498 #define AngelSVC_Reason_Close           0x02
13499 #define AngelSVC_Reason_Write           0x05
13500 #define AngelSVC_Reason_Read            0x06
13501 #define AngelSVC_Reason_IsTTY           0x09
13502 #define AngelSVC_Reason_Seek            0x0A
13503 #define AngelSVC_Reason_FLen            0x0C
13504 #define AngelSVC_Reason_Remove          0x0E
13505 #define AngelSVC_Reason_Rename          0x0F
13506 #define AngelSVC_Reason_Clock           0x10
13507 #define AngelSVC_Reason_Time            0x11
13508 #define AngelSVC_Reason_System          0x12
13509 #define AngelSVC_Reason_Errno           0x13
13510 #define AngelSVC_Reason_GetCmdLine      0x15
13511 #define AngelSVC_Reason_HeapInfo        0x16
13512 #define AngelSVC_Reason_ReportException 0x18
13513 #define AngelSVC_Reason_Elapsed         0x30
13514
13515
13516 static void
13517 handle_halt (sim_cpu *cpu, uint32_t val)
13518 {
13519   uint64_t result = 0;
13520
13521   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13522   if (val != 0xf000)
13523     {
13524       TRACE_SYSCALL (cpu, " HLT [0x%x]", val);
13525       sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
13526                        sim_stopped, SIM_SIGTRAP);
13527     }
13528
13529   /* We have encountered an Angel SVC call.  See if we can process it.  */
13530   switch (aarch64_get_reg_u32 (cpu, 0, NO_SP))
13531     {
13532     case AngelSVC_Reason_HeapInfo:
13533       {
13534         /* Get the values.  */
13535         uint64_t stack_top = aarch64_get_stack_start (cpu);
13536         uint64_t heap_base = aarch64_get_heap_start (cpu);
13537
13538         /* Get the pointer  */
13539         uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);
13540         ptr = aarch64_get_mem_u64 (cpu, ptr);
13541
13542         /* Fill in the memory block.  */
13543         /* Start addr of heap.  */
13544         aarch64_set_mem_u64 (cpu, ptr +  0, heap_base);
13545         /* End addr of heap.  */
13546         aarch64_set_mem_u64 (cpu, ptr +  8, stack_top);
13547         /* Lowest stack addr.  */
13548         aarch64_set_mem_u64 (cpu, ptr + 16, heap_base);
13549         /* Initial stack addr.  */
13550         aarch64_set_mem_u64 (cpu, ptr + 24, stack_top);
13551
13552         TRACE_SYSCALL (cpu, " AngelSVC: Get Heap Info");
13553       }
13554       break;
13555
13556     case AngelSVC_Reason_Open:
13557       {
13558         /* Get the pointer  */
13559         /* uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);.  */
13560         /* FIXME: For now we just assume that we will only be asked
13561            to open the standard file descriptors.  */
13562         static int fd = 0;
13563         result = fd ++;
13564
13565         TRACE_SYSCALL (cpu, " AngelSVC: Open file %d", fd - 1);
13566       }
13567       break;
13568
13569     case AngelSVC_Reason_Close:
13570       {
13571         uint64_t fh = aarch64_get_reg_u64 (cpu, 1, SP_OK);
13572         TRACE_SYSCALL (cpu, " AngelSVC: Close file %d", (int) fh);
13573         result = 0;
13574       }
13575       break;
13576
13577     case AngelSVC_Reason_Errno:
13578       result = 0;
13579       TRACE_SYSCALL (cpu, " AngelSVC: Get Errno");
13580       break;
13581
13582     case AngelSVC_Reason_Clock:
13583       result =
13584 #ifdef CLOCKS_PER_SEC
13585         (CLOCKS_PER_SEC >= 100)
13586         ? (clock () / (CLOCKS_PER_SEC / 100))
13587         : ((clock () * 100) / CLOCKS_PER_SEC)
13588 #else
13589         /* Presume unix... clock() returns microseconds.  */
13590         (clock () / 10000)
13591 #endif
13592         ;
13593         TRACE_SYSCALL (cpu, " AngelSVC: Get Clock");
13594       break;
13595
13596     case AngelSVC_Reason_GetCmdLine:
13597       {
13598         /* Get the pointer  */
13599         uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);
13600         ptr = aarch64_get_mem_u64 (cpu, ptr);
13601
13602         /* FIXME: No command line for now.  */
13603         aarch64_set_mem_u64 (cpu, ptr, 0);
13604         TRACE_SYSCALL (cpu, " AngelSVC: Get Command Line");
13605       }
13606       break;
13607
13608     case AngelSVC_Reason_IsTTY:
13609       result = 1;
13610         TRACE_SYSCALL (cpu, " AngelSVC: IsTTY ?");
13611       break;
13612
13613     case AngelSVC_Reason_Write:
13614       {
13615         /* Get the pointer  */
13616         uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);
13617         /* Get the write control block.  */
13618         uint64_t fd  = aarch64_get_mem_u64 (cpu, ptr);
13619         uint64_t buf = aarch64_get_mem_u64 (cpu, ptr + 8);
13620         uint64_t len = aarch64_get_mem_u64 (cpu, ptr + 16);
13621
13622         TRACE_SYSCALL (cpu, "write of %" PRIx64 " bytes from %"
13623                        PRIx64 " on descriptor %" PRIx64,
13624                        len, buf, fd);
13625
13626         if (len > 1280)
13627           {
13628             TRACE_SYSCALL (cpu,
13629                            " AngelSVC: Write: Suspiciously long write: %ld",
13630                            (long) len);
13631             sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
13632                              sim_stopped, SIM_SIGBUS);
13633           }
13634         else if (fd == 1)
13635           {
13636             printf ("%.*s", (int) len, aarch64_get_mem_ptr (cpu, buf));
13637           }
13638         else if (fd == 2)
13639           {
13640             TRACE (cpu, 0, "\n");
13641             sim_io_eprintf (CPU_STATE (cpu), "%.*s",
13642                             (int) len, aarch64_get_mem_ptr (cpu, buf));
13643             TRACE (cpu, 0, "\n");
13644           }
13645         else
13646           {
13647             TRACE_SYSCALL (cpu,
13648                            " AngelSVC: Write: Unexpected file handle: %d",
13649                            (int) fd);
13650             sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
13651                              sim_stopped, SIM_SIGABRT);
13652           }
13653       }
13654       break;
13655
13656     case AngelSVC_Reason_ReportException:
13657       {
13658         /* Get the pointer  */
13659         uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);
13660         /*ptr = aarch64_get_mem_u64 (cpu, ptr);.  */
13661         uint64_t type = aarch64_get_mem_u64 (cpu, ptr);
13662         uint64_t state = aarch64_get_mem_u64 (cpu, ptr + 8);
13663
13664         TRACE_SYSCALL (cpu,
13665                        "Angel Exception: type 0x%" PRIx64 " state %" PRIx64,
13666                        type, state);
13667
13668         if (type == 0x20026)
13669           sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
13670                            sim_exited, state);
13671         else
13672           sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
13673                            sim_stopped, SIM_SIGINT);
13674       }
13675       break;
13676
13677     case AngelSVC_Reason_Read:
13678     case AngelSVC_Reason_FLen:
13679     case AngelSVC_Reason_Seek:
13680     case AngelSVC_Reason_Remove:
13681     case AngelSVC_Reason_Time:
13682     case AngelSVC_Reason_System:
13683     case AngelSVC_Reason_Rename:
13684     case AngelSVC_Reason_Elapsed:
13685     default:
13686       TRACE_SYSCALL (cpu, " HLT [Unknown angel %x]",
13687                      aarch64_get_reg_u32 (cpu, 0, NO_SP));
13688       sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
13689                        sim_stopped, SIM_SIGTRAP);
13690     }
13691
13692   aarch64_set_reg_u64 (cpu, 0, NO_SP, result);
13693 }
13694
13695 static void
13696 dexExcpnGen (sim_cpu *cpu)
13697 {
13698   /* instr[31:24] = 11010100
13699      instr[23,21] = opc : 000 ==> GEN EXCPN, 001 ==> BRK
13700                           010 ==> HLT,       101 ==> DBG GEN EXCPN
13701      instr[20,5]  = imm16
13702      instr[4,2]   = opc2 000 ==> OK, ow ==> UNALLOC
13703      instr[1,0]   = LL : discriminates opc  */
13704
13705   uint32_t opc = INSTR (23, 21);
13706   uint32_t imm16 = INSTR (20, 5);
13707   uint32_t opc2 = INSTR (4, 2);
13708   uint32_t LL;
13709
13710   NYI_assert (31, 24, 0xd4);
13711
13712   if (opc2 != 0)
13713     HALT_UNALLOC;
13714
13715   LL = INSTR (1, 0);
13716
13717   /* We only implement HLT and BRK for now.  */
13718   if (opc == 1 && LL == 0)
13719     {
13720       TRACE_EVENTS (cpu, " BRK [0x%x]", imm16);
13721       sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
13722                        sim_exited, aarch64_get_reg_s32 (cpu, R0, SP_OK));
13723     }
13724
13725   if (opc == 2 && LL == 0)
13726     handle_halt (cpu, imm16);
13727
13728   else if (opc == 0 || opc == 5)
13729     HALT_NYI;
13730
13731   else
13732     HALT_UNALLOC;
13733 }
13734
13735 /* Stub for accessing system registers.  */
13736
13737 static uint64_t
13738 system_get (sim_cpu *cpu, unsigned op0, unsigned op1, unsigned crn,
13739             unsigned crm, unsigned op2)
13740 {
13741   if (crn == 0 && op1 == 3 && crm == 0 && op2 == 7)
13742     /* DCZID_EL0 - the Data Cache Zero ID register.
13743        We do not support DC ZVA at the moment, so
13744        we return a value with the disable bit set.
13745        We implement support for the DCZID register since
13746        it is used by the C library's memset function.  */
13747     return ((uint64_t) 1) << 4;
13748
13749   if (crn == 0 && op1 == 3 && crm == 0 && op2 == 1)
13750     /* Cache Type Register.  */
13751     return 0x80008000UL;
13752
13753   if (crn == 13 && op1 == 3 && crm == 0 && op2 == 2)
13754     /* TPIDR_EL0 - thread pointer id.  */
13755     return aarch64_get_thread_id (cpu);
13756
13757   if (op1 == 3 && crm == 4 && op2 == 0)
13758     return aarch64_get_FPCR (cpu);
13759
13760   if (op1 == 3 && crm == 4 && op2 == 1)
13761     return aarch64_get_FPSR (cpu);
13762
13763   else if (op1 == 3 && crm == 2 && op2 == 0)
13764     return aarch64_get_CPSR (cpu);
13765
13766   HALT_NYI;
13767 }
13768
13769 static void
13770 system_set (sim_cpu *cpu, unsigned op0, unsigned op1, unsigned crn,
13771             unsigned crm, unsigned op2, uint64_t val)
13772 {
13773   if (op1 == 3 && crm == 4 && op2 == 0)
13774     aarch64_set_FPCR (cpu, val);
13775
13776   else if (op1 == 3 && crm == 4 && op2 == 1)
13777     aarch64_set_FPSR (cpu, val);
13778
13779   else if (op1 == 3 && crm == 2 && op2 == 0)
13780     aarch64_set_CPSR (cpu, val);
13781
13782   else
13783     HALT_NYI;
13784 }
13785
13786 static void
13787 do_mrs (sim_cpu *cpu)
13788 {
13789   /* instr[31:20] = 1101 0101 0001 1
13790      instr[19]    = op0
13791      instr[18,16] = op1
13792      instr[15,12] = CRn
13793      instr[11,8]  = CRm
13794      instr[7,5]   = op2
13795      instr[4,0]   = Rt  */
13796   unsigned sys_op0 = INSTR (19, 19) + 2;
13797   unsigned sys_op1 = INSTR (18, 16);
13798   unsigned sys_crn = INSTR (15, 12);
13799   unsigned sys_crm = INSTR (11, 8);
13800   unsigned sys_op2 = INSTR (7, 5);
13801   unsigned rt = INSTR (4, 0);
13802
13803   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13804   aarch64_set_reg_u64 (cpu, rt, NO_SP,
13805                        system_get (cpu, sys_op0, sys_op1, sys_crn, sys_crm, sys_op2));
13806 }
13807
13808 static void
13809 do_MSR_immediate (sim_cpu *cpu)
13810 {
13811   /* instr[31:19] = 1101 0101 0000 0
13812      instr[18,16] = op1
13813      instr[15,12] = 0100
13814      instr[11,8]  = CRm
13815      instr[7,5]   = op2
13816      instr[4,0]   = 1 1111  */
13817
13818   unsigned op1 = INSTR (18, 16);
13819   /*unsigned crm = INSTR (11, 8);*/
13820   unsigned op2 = INSTR (7, 5);
13821
13822   NYI_assert (31, 19, 0x1AA0);
13823   NYI_assert (15, 12, 0x4);
13824   NYI_assert (4,  0,  0x1F);
13825
13826   if (op1 == 0)
13827     {
13828       if (op2 == 5)
13829         HALT_NYI; /* set SPSel.  */
13830       else
13831         HALT_UNALLOC;
13832     }
13833   else if (op1 == 3)
13834     {
13835       if (op2 == 6)
13836         HALT_NYI; /* set DAIFset.  */
13837       else if (op2 == 7)
13838         HALT_NYI; /* set DAIFclr.  */
13839       else
13840         HALT_UNALLOC;
13841     }
13842   else
13843     HALT_UNALLOC;
13844 }
13845
13846 static void
13847 do_MSR_reg (sim_cpu *cpu)
13848 {
13849   /* instr[31:20] = 1101 0101 0001
13850      instr[19]    = op0
13851      instr[18,16] = op1
13852      instr[15,12] = CRn
13853      instr[11,8]  = CRm
13854      instr[7,5]   = op2
13855      instr[4,0]   = Rt  */
13856
13857   unsigned sys_op0 = INSTR (19, 19) + 2;
13858   unsigned sys_op1 = INSTR (18, 16);
13859   unsigned sys_crn = INSTR (15, 12);
13860   unsigned sys_crm = INSTR (11, 8);
13861   unsigned sys_op2 = INSTR (7, 5);
13862   unsigned rt = INSTR (4, 0);
13863
13864   NYI_assert (31, 20, 0xD51);
13865
13866   TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
13867   system_set (cpu, sys_op0, sys_op1, sys_crn, sys_crm, sys_op2,
13868               aarch64_get_reg_u64 (cpu, rt, NO_SP));
13869 }
13870
13871 static void
13872 do_SYS (sim_cpu *cpu)
13873 {
13874   /* instr[31,19] = 1101 0101 0000 1
13875      instr[18,16] = op1
13876      instr[15,12] = CRn
13877      instr[11,8]  = CRm
13878      instr[7,5]   = op2
13879      instr[4,0]   = Rt  */
13880   NYI_assert (31, 19, 0x1AA1);
13881
13882   /* FIXME: For now we just silently accept system ops.  */
13883 }
13884
13885 static void
13886 dexSystem (sim_cpu *cpu)
13887 {
13888   /* instr[31:22] = 1101 01010 0
13889      instr[21]    = L
13890      instr[20,19] = op0
13891      instr[18,16] = op1
13892      instr[15,12] = CRn
13893      instr[11,8]  = CRm
13894      instr[7,5]   = op2
13895      instr[4,0]   = uimm5  */
13896
13897   /* We are interested in HINT, DSB, DMB and ISB
13898
13899      Hint #0 encodes NOOP (this is the only hint we care about)
13900      L == 0, op0 == 0, op1 = 011, CRn = 0010, Rt = 11111,
13901      CRm op2  != 0000 000 OR CRm op2 == 0000 000 || CRm op > 0000 101
13902
13903      DSB, DMB, ISB are data store barrier, data memory barrier and
13904      instruction store barrier, respectively, where
13905
13906      L == 0, op0 == 0, op1 = 011, CRn = 0011, Rt = 11111,
13907      op2 : DSB ==> 100, DMB ==> 101, ISB ==> 110
13908      CRm<3:2> ==> domain, CRm<1:0> ==> types,
13909      domain : 00 ==> OuterShareable, 01 ==> Nonshareable,
13910               10 ==> InerShareable, 11 ==> FullSystem
13911      types :  01 ==> Reads, 10 ==> Writes,
13912               11 ==> All, 00 ==> All (domain == FullSystem).  */
13913
13914   unsigned rt = INSTR (4, 0);
13915
13916   NYI_assert (31, 22, 0x354);
13917
13918   switch (INSTR (21, 12))
13919     {
13920     case 0x032:
13921       if (rt == 0x1F)
13922         {
13923           /* NOP has CRm != 0000 OR.  */
13924           /*         (CRm == 0000 AND (op2 == 000 OR op2 > 101)).  */
13925           uint32_t crm = INSTR (11, 8);
13926           uint32_t op2 = INSTR (7, 5);
13927
13928           if (crm != 0 || (op2 == 0 || op2 > 5))
13929             {
13930               /* Actually call nop method so we can reimplement it later.  */
13931               nop (cpu);
13932               return;
13933             }
13934         }
13935       HALT_NYI;
13936
13937     case 0x033:
13938       {
13939         uint32_t op2 =  INSTR (7, 5);
13940
13941         switch (op2)
13942           {
13943           case 2: HALT_NYI;
13944           case 4: dsb (cpu); return;
13945           case 5: dmb (cpu); return;
13946           case 6: isb (cpu); return;
13947           default: HALT_UNALLOC;
13948         }
13949       }
13950
13951     case 0x3B0:
13952     case 0x3B4:
13953     case 0x3BD:
13954       do_mrs (cpu);
13955       return;
13956
13957     case 0x0B7:
13958       do_SYS (cpu); /* DC is an alias of SYS.  */
13959       return;
13960
13961     default:
13962       if (INSTR (21, 20) == 0x1)
13963         do_MSR_reg (cpu);
13964       else if (INSTR (21, 19) == 0 && INSTR (15, 12) == 0x4)
13965         do_MSR_immediate (cpu);
13966       else
13967         HALT_NYI;
13968       return;
13969     }
13970 }
13971
13972 static void
13973 dexBr (sim_cpu *cpu)
13974 {
13975   /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu));
13976      assert  group == GROUP_BREXSYS_1010 || group == GROUP_BREXSYS_1011
13977      bits [31,29] of a BrExSys are the secondary dispatch vector.  */
13978   uint32_t group2 = dispatchBrExSys (aarch64_get_instr (cpu));
13979
13980   switch (group2)
13981     {
13982     case BR_IMM_000:
13983       return dexBranchImmediate (cpu);
13984
13985     case BR_IMMCMP_001:
13986       /* Compare has bit 25 clear while test has it set.  */
13987       if (!INSTR (25, 25))
13988         dexCompareBranchImmediate (cpu);
13989       else
13990         dexTestBranchImmediate (cpu);
13991       return;
13992
13993     case BR_IMMCOND_010:
13994       /* This is a conditional branch if bit 25 is clear otherwise
13995          unallocated.  */
13996       if (!INSTR (25, 25))
13997         dexCondBranchImmediate (cpu);
13998       else
13999         HALT_UNALLOC;
14000       return;
14001
14002     case BR_UNALLOC_011:
14003       HALT_UNALLOC;
14004
14005     case BR_IMM_100:
14006       dexBranchImmediate (cpu);
14007       return;
14008
14009     case BR_IMMCMP_101:
14010       /* Compare has bit 25 clear while test has it set.  */
14011       if (!INSTR (25, 25))
14012         dexCompareBranchImmediate (cpu);
14013       else
14014         dexTestBranchImmediate (cpu);
14015       return;
14016
14017     case BR_REG_110:
14018       /* Unconditional branch reg has bit 25 set.  */
14019       if (INSTR (25, 25))
14020         dexBranchRegister (cpu);
14021
14022       /* This includes both Excpn Gen, System and unalloc operations.
14023          We need to decode the Excpn Gen operation BRK so we can plant
14024          debugger entry points.
14025          Excpn Gen operations have instr [24] = 0.
14026          we need to decode at least one of the System operations NOP
14027          which is an alias for HINT #0.
14028          System operations have instr [24,22] = 100.  */
14029       else if (INSTR (24, 24) == 0)
14030         dexExcpnGen (cpu);
14031
14032       else if (INSTR (24, 22) == 4)
14033         dexSystem (cpu);
14034
14035       else
14036         HALT_UNALLOC;
14037
14038       return;
14039
14040     case BR_UNALLOC_111:
14041       HALT_UNALLOC;
14042
14043     default:
14044       /* Should never reach here.  */
14045       HALT_NYI;
14046     }
14047 }
14048
14049 static void
14050 aarch64_decode_and_execute (sim_cpu *cpu, uint64_t pc)
14051 {
14052   /* We need to check if gdb wants an in here.  */
14053   /* checkBreak (cpu);.  */
14054
14055   uint64_t group = dispatchGroup (aarch64_get_instr (cpu));
14056
14057   switch (group)
14058     {
14059     case GROUP_PSEUDO_0000:   dexPseudo (cpu); break;
14060     case GROUP_LDST_0100:     dexLdSt (cpu); break;
14061     case GROUP_DPREG_0101:    dexDPReg (cpu); break;
14062     case GROUP_LDST_0110:     dexLdSt (cpu); break;
14063     case GROUP_ADVSIMD_0111:  dexAdvSIMD0 (cpu); break;
14064     case GROUP_DPIMM_1000:    dexDPImm (cpu); break;
14065     case GROUP_DPIMM_1001:    dexDPImm (cpu); break;
14066     case GROUP_BREXSYS_1010:  dexBr (cpu); break;
14067     case GROUP_BREXSYS_1011:  dexBr (cpu); break;
14068     case GROUP_LDST_1100:     dexLdSt (cpu); break;
14069     case GROUP_DPREG_1101:    dexDPReg (cpu); break;
14070     case GROUP_LDST_1110:     dexLdSt (cpu); break;
14071     case GROUP_ADVSIMD_1111:  dexAdvSIMD1 (cpu); break;
14072
14073     case GROUP_UNALLOC_0001:
14074     case GROUP_UNALLOC_0010:
14075     case GROUP_UNALLOC_0011:
14076       HALT_UNALLOC;
14077
14078     default:
14079       /* Should never reach here.  */
14080       HALT_NYI;
14081     }
14082 }
14083
14084 static bfd_boolean
14085 aarch64_step (sim_cpu *cpu)
14086 {
14087   uint64_t pc = aarch64_get_PC (cpu);
14088
14089   if (pc == TOP_LEVEL_RETURN_PC)
14090     return FALSE;
14091
14092   aarch64_set_next_PC (cpu, pc + 4);
14093
14094   /* Code is always little-endian.  */
14095   sim_core_read_buffer (CPU_STATE (cpu), cpu, read_map,
14096                         & aarch64_get_instr (cpu), pc, 4);
14097   aarch64_get_instr (cpu) = endian_le2h_4 (aarch64_get_instr (cpu));
14098
14099   TRACE_INSN (cpu, " pc = %" PRIx64 " instr = %08x", pc,
14100               aarch64_get_instr (cpu));
14101   TRACE_DISASM (cpu, pc);
14102
14103   aarch64_decode_and_execute (cpu, pc);
14104
14105   return TRUE;
14106 }
14107
14108 void
14109 aarch64_run (SIM_DESC sd)
14110 {
14111   sim_cpu *cpu = STATE_CPU (sd, 0);
14112
14113   while (aarch64_step (cpu))
14114     {
14115       aarch64_update_PC (cpu);
14116
14117       if (sim_events_tick (sd))
14118         sim_events_process (sd);
14119     }
14120
14121   sim_engine_halt (sd, cpu, NULL, aarch64_get_PC (cpu),
14122                    sim_exited, aarch64_get_reg_s32 (cpu, R0, NO_SP));
14123 }
14124
14125 void
14126 aarch64_init (sim_cpu *cpu, uint64_t pc)
14127 {
14128   uint64_t sp = aarch64_get_stack_start (cpu);
14129
14130   /* Install SP, FP and PC and set LR to -20
14131      so we can detect a top-level return.  */
14132   aarch64_set_reg_u64 (cpu, SP, SP_OK, sp);
14133   aarch64_set_reg_u64 (cpu, FP, SP_OK, sp);
14134   aarch64_set_reg_u64 (cpu, LR, SP_OK, TOP_LEVEL_RETURN_PC);
14135   aarch64_set_next_PC (cpu, pc);
14136   aarch64_update_PC (cpu);
14137   aarch64_init_LIT_table ();
14138 }