xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/bfin/bfin-sim.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Simulator for Analog Devices Blackfin processors.
2 
3    Copyright (C) 2005-2023 Free Software Foundation, Inc.
4    Contributed by Analog Devices, Inc.
5 
6    This file is part of simulators.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 /* This must come before any other includes.  */
22 #include "defs.h"
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <inttypes.h>
28 
29 #include "ansidecl.h"
30 #include "opcode/bfin.h"
31 #include "sim-main.h"
32 #include "dv-bfin_cec.h"
33 #include "dv-bfin_mmu.h"
34 
35 #define HOST_LONG_WORD_SIZE (sizeof (long) * 8)
36 
37 #define SIGNEXTEND(v, n) \
38   (((bs32)(v) << (HOST_LONG_WORD_SIZE - (n))) >> (HOST_LONG_WORD_SIZE - (n)))
39 
40 static ATTRIBUTE_NORETURN void
41 illegal_instruction (SIM_CPU *cpu)
42 {
43   TRACE_INSN (cpu, "ILLEGAL INSTRUCTION");
44   while (1)
45     cec_exception (cpu, VEC_UNDEF_I);
46 }
47 
48 static ATTRIBUTE_NORETURN void
49 illegal_instruction_combination (SIM_CPU *cpu)
50 {
51   TRACE_INSN (cpu, "ILLEGAL INSTRUCTION COMBINATION");
52   while (1)
53     cec_exception (cpu, VEC_ILGAL_I);
54 }
55 
56 static ATTRIBUTE_NORETURN void
57 illegal_instruction_or_combination (SIM_CPU *cpu)
58 {
59   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
60     illegal_instruction_combination (cpu);
61   else
62     illegal_instruction (cpu);
63 }
64 
65 static ATTRIBUTE_NORETURN void
66 unhandled_instruction (SIM_CPU *cpu, const char *insn)
67 {
68   SIM_DESC sd = CPU_STATE (cpu);
69   bu16 iw0, iw1;
70   bu32 iw2;
71 
72   TRACE_EVENTS (cpu, "unhandled instruction");
73 
74   iw0 = IFETCH (PCREG);
75   iw1 = IFETCH (PCREG + 2);
76   iw2 = ((bu32)iw0 << 16) | iw1;
77 
78   sim_io_eprintf (sd, "Unhandled instruction at 0x%08x (%s opcode 0x", PCREG, insn);
79   if ((iw0 & 0xc000) == 0xc000)
80     sim_io_eprintf (sd, "%08x", iw2);
81   else
82     sim_io_eprintf (sd, "%04x", iw0);
83 
84   sim_io_eprintf (sd, ") ... aborting\n");
85 
86   illegal_instruction (cpu);
87 }
88 
89 static const char * const astat_names[] =
90 {
91   [ 0] = "AZ",
92   [ 1] = "AN",
93   [ 2] = "AC0_COPY",
94   [ 3] = "V_COPY",
95   [ 4] = "ASTAT_4",
96   [ 5] = "CC",
97   [ 6] = "AQ",
98   [ 7] = "ASTAT_7",
99   [ 8] = "RND_MOD",
100   [ 9] = "ASTAT_9",
101   [10] = "ASTAT_10",
102   [11] = "ASTAT_11",
103   [12] = "AC0",
104   [13] = "AC1",
105   [14] = "ASTAT_14",
106   [15] = "ASTAT_15",
107   [16] = "AV0",
108   [17] = "AV0S",
109   [18] = "AV1",
110   [19] = "AV1S",
111   [20] = "ASTAT_20",
112   [21] = "ASTAT_21",
113   [22] = "ASTAT_22",
114   [23] = "ASTAT_23",
115   [24] = "V",
116   [25] = "VS",
117   [26] = "ASTAT_26",
118   [27] = "ASTAT_27",
119   [28] = "ASTAT_28",
120   [29] = "ASTAT_29",
121   [30] = "ASTAT_30",
122   [31] = "ASTAT_31",
123 };
124 
125 typedef enum
126 {
127   c_0, c_1, c_4, c_2, c_uimm2, c_uimm3, c_imm3, c_pcrel4,
128   c_imm4, c_uimm4s4, c_uimm4s4d, c_uimm4, c_uimm4s2, c_negimm5s4, c_imm5,
129   c_imm5d, c_uimm5, c_imm6, c_imm7, c_imm7d, c_imm8, c_uimm8, c_pcrel8,
130   c_uimm8s4, c_pcrel8s4, c_lppcrel10, c_pcrel10, c_pcrel12, c_imm16s4,
131   c_luimm16, c_imm16, c_imm16d, c_huimm16, c_rimm16, c_imm16s2, c_uimm16s4,
132   c_uimm16s4d, c_uimm16, c_pcrel24, c_uimm32, c_imm32, c_huimm32, c_huimm32e,
133 } const_forms_t;
134 
135 static const struct
136 {
137   const char *name;
138   const int nbits;
139   const char reloc;
140   const char issigned;
141   const char pcrel;
142   const char scale;
143   const char offset;
144   const char negative;
145   const char positive;
146   const char decimal;
147   const char leading;
148   const char exact;
149 } constant_formats[] =
150 {
151   { "0",          0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
152   { "1",          0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
153   { "4",          0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
154   { "2",          0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
155   { "uimm2",      2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
156   { "uimm3",      3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
157   { "imm3",       3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
158   { "pcrel4",     4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
159   { "imm4",       4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
160   { "uimm4s4",    4, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0},
161   { "uimm4s4d",   4, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0},
162   { "uimm4",      4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
163   { "uimm4s2",    4, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0},
164   { "negimm5s4",  5, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0},
165   { "imm5",       5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
166   { "imm5d",      5, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
167   { "uimm5",      5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
168   { "imm6",       6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
169   { "imm7",       7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
170   { "imm7d",      7, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
171   { "imm8",       8, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
172   { "uimm8",      8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
173   { "pcrel8",     8, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
174   { "uimm8s4",    8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
175   { "pcrel8s4",   8, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
176   { "lppcrel10", 10, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
177   { "pcrel10",   10, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
178   { "pcrel12",   12, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
179   { "imm16s4",   16, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0},
180   { "luimm16",   16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
181   { "imm16",     16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
182   { "imm16d",    16, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
183   { "huimm16",   16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
184   { "rimm16",    16, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
185   { "imm16s2",   16, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
186   { "uimm16s4",  16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
187   { "uimm16s4d", 16, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0},
188   { "uimm16",    16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
189   { "pcrel24",   24, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
190   { "uimm32",    32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
191   { "imm32",     32, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
192   { "huimm32",   32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
193   { "huimm32e",  32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
194 };
195 
196 static const char *
197 fmtconst_str (const_forms_t cf, bs32 x, bu32 pc)
198 {
199   static char buf[60];
200 
201   if (constant_formats[cf].reloc)
202     {
203       bu32 ea = (((constant_formats[cf].pcrel ? SIGNEXTEND (x, constant_formats[cf].nbits)
204 		      : x) + constant_formats[cf].offset) << constant_formats[cf].scale);
205       if (constant_formats[cf].pcrel)
206 	ea += pc;
207      /*if (outf->symbol_at_address_func (ea, outf) || !constant_formats[cf].exact)
208        {
209 	  outf->print_address_func (ea, outf);
210 	  return "";
211        }
212      else*/
213        {
214 	  sprintf (buf, "%#x", x);
215 	  return buf;
216        }
217     }
218 
219   /* Negative constants have an implied sign bit.  */
220   if (constant_formats[cf].negative)
221     {
222       int nb = constant_formats[cf].nbits + 1;
223 
224       x = x | (1 << constant_formats[cf].nbits);
225       x = SIGNEXTEND (x, nb);
226     }
227   else
228     x = constant_formats[cf].issigned ? SIGNEXTEND (x, constant_formats[cf].nbits) : x;
229 
230   if (constant_formats[cf].offset)
231     x += constant_formats[cf].offset;
232 
233   if (constant_formats[cf].scale)
234     x <<= constant_formats[cf].scale;
235 
236   if (constant_formats[cf].decimal)
237     sprintf (buf, "%*i", constant_formats[cf].leading, x);
238   else
239     {
240       if (constant_formats[cf].issigned && x < 0)
241 	sprintf (buf, "-0x%x", abs (x));
242       else
243 	sprintf (buf, "0x%x", x);
244     }
245 
246   return buf;
247 }
248 
249 static bu32
250 fmtconst_val (const_forms_t cf, bu32 x, bu32 pc)
251 {
252   if (0 && constant_formats[cf].reloc)
253     {
254       bu32 ea = (((constant_formats[cf].pcrel
255 		   ? (bu32)SIGNEXTEND (x, constant_formats[cf].nbits)
256 		   : x) + constant_formats[cf].offset)
257 		 << constant_formats[cf].scale);
258       if (constant_formats[cf].pcrel)
259 	ea += pc;
260 
261       return ea;
262     }
263 
264   /* Negative constants have an implied sign bit.  */
265   if (constant_formats[cf].negative)
266     {
267       int nb = constant_formats[cf].nbits + 1;
268       x = x | (1 << constant_formats[cf].nbits);
269       x = SIGNEXTEND (x, nb);
270     }
271   else if (constant_formats[cf].issigned)
272     x = SIGNEXTEND (x, constant_formats[cf].nbits);
273 
274   x += constant_formats[cf].offset;
275   x <<= constant_formats[cf].scale;
276 
277   return x;
278 }
279 
280 #define uimm16s4(x)	fmtconst_val (c_uimm16s4, x, 0)
281 #define uimm16s4_str(x)	fmtconst_str (c_uimm16s4, x, 0)
282 #define uimm16s4d(x)	fmtconst_val (c_uimm16s4d, x, 0)
283 #define pcrel4(x)	fmtconst_val (c_pcrel4, x, pc)
284 #define pcrel8(x)	fmtconst_val (c_pcrel8, x, pc)
285 #define pcrel8s4(x)	fmtconst_val (c_pcrel8s4, x, pc)
286 #define pcrel10(x)	fmtconst_val (c_pcrel10, x, pc)
287 #define pcrel12(x)	fmtconst_val (c_pcrel12, x, pc)
288 #define negimm5s4(x)	fmtconst_val (c_negimm5s4, x, 0)
289 #define negimm5s4_str(x)	fmtconst_str (c_negimm5s4, x, 0)
290 #define rimm16(x)	fmtconst_val (c_rimm16, x, 0)
291 #define huimm16(x)	fmtconst_val (c_huimm16, x, 0)
292 #define imm16(x)	fmtconst_val (c_imm16, x, 0)
293 #define imm16_str(x)	fmtconst_str (c_imm16, x, 0)
294 #define imm16d(x)	fmtconst_val (c_imm16d, x, 0)
295 #define uimm2(x)	fmtconst_val (c_uimm2, x, 0)
296 #define uimm3(x)	fmtconst_val (c_uimm3, x, 0)
297 #define uimm3_str(x)	fmtconst_str (c_uimm3, x, 0)
298 #define luimm16(x)	fmtconst_val (c_luimm16, x, 0)
299 #define luimm16_str(x)	fmtconst_str (c_luimm16, x, 0)
300 #define uimm4(x)	fmtconst_val (c_uimm4, x, 0)
301 #define uimm4_str(x)	fmtconst_str (c_uimm4, x, 0)
302 #define uimm5(x)	fmtconst_val (c_uimm5, x, 0)
303 #define uimm5_str(x)	fmtconst_str (c_uimm5, x, 0)
304 #define imm16s2(x)	fmtconst_val (c_imm16s2, x, 0)
305 #define imm16s2_str(x)	fmtconst_str (c_imm16s2, x, 0)
306 #define uimm8(x)	fmtconst_val (c_uimm8, x, 0)
307 #define imm16s4(x)	fmtconst_val (c_imm16s4, x, 0)
308 #define imm16s4_str(x)	fmtconst_str (c_imm16s4, x, 0)
309 #define uimm4s2(x)	fmtconst_val (c_uimm4s2, x, 0)
310 #define uimm4s2_str(x)	fmtconst_str (c_uimm4s2, x, 0)
311 #define uimm4s4(x)	fmtconst_val (c_uimm4s4, x, 0)
312 #define uimm4s4_str(x)	fmtconst_str (c_uimm4s4, x, 0)
313 #define uimm4s4d(x)	fmtconst_val (c_uimm4s4d, x, 0)
314 #define lppcrel10(x)	fmtconst_val (c_lppcrel10, x, pc)
315 #define imm3(x)		fmtconst_val (c_imm3, x, 0)
316 #define imm3_str(x)	fmtconst_str (c_imm3, x, 0)
317 #define imm4(x)		fmtconst_val (c_imm4, x, 0)
318 #define uimm8s4(x)	fmtconst_val (c_uimm8s4, x, 0)
319 #define imm5(x)		fmtconst_val (c_imm5, x, 0)
320 #define imm5d(x)	fmtconst_val (c_imm5d, x, 0)
321 #define imm6(x)		fmtconst_val (c_imm6, x, 0)
322 #define imm7(x)		fmtconst_val (c_imm7, x, 0)
323 #define imm7_str(x)	fmtconst_str (c_imm7, x, 0)
324 #define imm7d(x)	fmtconst_val (c_imm7d, x, 0)
325 #define imm8(x)		fmtconst_val (c_imm8, x, 0)
326 #define pcrel24(x)	fmtconst_val (c_pcrel24, x, pc)
327 #define pcrel24_str(x)	fmtconst_str (c_pcrel24, x, pc)
328 #define uimm16(x)	fmtconst_val (c_uimm16, x, 0)
329 #define uimm32(x)	fmtconst_val (c_uimm32, x, 0)
330 #define imm32(x)	fmtconst_val (c_imm32, x, 0)
331 #define huimm32(x)	fmtconst_val (c_huimm32, x, 0)
332 #define huimm32e(x)	fmtconst_val (c_huimm32e, x, 0)
333 
334 /* Table C-4. Core Register Encoding Map.  */
335 const char * const greg_names[] =
336 {
337   "R0",    "R1",      "R2",     "R3",    "R4",    "R5",    "R6",     "R7",
338   "P0",    "P1",      "P2",     "P3",    "P4",    "P5",    "SP",     "FP",
339   "I0",    "I1",      "I2",     "I3",    "M0",    "M1",    "M2",     "M3",
340   "B0",    "B1",      "B2",     "B3",    "L0",    "L1",    "L2",     "L3",
341   "A0.X",  "A0.W",    "A1.X",   "A1.W",  "<res>", "<res>", "ASTAT",  "RETS",
342   "<res>", "<res>",   "<res>",  "<res>", "<res>", "<res>", "<res>",  "<res>",
343   "LC0",   "LT0",     "LB0",    "LC1",   "LT1",   "LB1",   "CYCLES", "CYCLES2",
344   "USP",   "SEQSTAT", "SYSCFG", "RETI",  "RETX",  "RETN",  "RETE",   "EMUDAT",
345 };
346 static const char *
347 get_allreg_name (int grp, int reg)
348 {
349   return greg_names[(grp << 3) | reg];
350 }
351 static const char *
352 get_preg_name (int reg)
353 {
354   return get_allreg_name (1, reg);
355 }
356 
357 static bool
358 reg_is_reserved (int grp, int reg)
359 {
360   return (grp == 4 && (reg == 4 || reg == 5)) || (grp == 5);
361 }
362 
363 static bu32 *
364 get_allreg (SIM_CPU *cpu, int grp, int reg)
365 {
366   int fullreg = (grp << 3) | reg;
367   /* REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
368      REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
369      REG_I0, REG_I1, REG_I2, REG_I3, REG_M0, REG_M1, REG_M2, REG_M3,
370      REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3,
371      REG_A0x, REG_A0w, REG_A1x, REG_A1w, , , REG_ASTAT, REG_RETS,
372      , , , , , , , ,
373      REG_LC0, REG_LT0, REG_LB0, REG_LC1, REG_LT1, REG_LB1, REG_CYCLES,
374      REG_CYCLES2,
375      REG_USP, REG_SEQSTAT, REG_SYSCFG, REG_RETI, REG_RETX, REG_RETN, REG_RETE,
376      REG_LASTREG  */
377   switch (fullreg >> 2)
378     {
379     case 0: case 1: return &DREG (reg);
380     case 2: case 3: return &PREG (reg);
381     case 4: return &IREG (reg & 3);
382     case 5: return &MREG (reg & 3);
383     case 6: return &BREG (reg & 3);
384     case 7: return &LREG (reg & 3);
385     default:
386       switch (fullreg)
387 	{
388 	case 32: return &AXREG (0);
389 	case 33: return &AWREG (0);
390 	case 34: return &AXREG (1);
391 	case 35: return &AWREG (1);
392 	case 39: return &RETSREG;
393 	case 48: return &LCREG (0);
394 	case 49: return &LTREG (0);
395 	case 50: return &LBREG (0);
396 	case 51: return &LCREG (1);
397 	case 52: return &LTREG (1);
398 	case 53: return &LBREG (1);
399 	case 54: return &CYCLESREG;
400 	case 55: return &CYCLES2REG;
401 	case 56: return &USPREG;
402 	case 57: return &SEQSTATREG;
403 	case 58: return &SYSCFGREG;
404 	case 59: return &RETIREG;
405 	case 60: return &RETXREG;
406 	case 61: return &RETNREG;
407 	case 62: return &RETEREG;
408 	case 63: return &EMUDAT_INREG;
409 	}
410       illegal_instruction (cpu);
411     }
412 }
413 
414 static const char *
415 amod0 (int s0, int x0)
416 {
417   static const char * const mod0[] = {
418     "", " (S)", " (CO)", " (SCO)",
419   };
420   int i = s0 + (x0 << 1);
421 
422   if (i < ARRAY_SIZE (mod0))
423     return mod0[i];
424   else
425     return "";
426 }
427 
428 static const char *
429 amod0amod2 (int s0, int x0, int aop0)
430 {
431   static const char * const mod02[] = {
432     "", " (S)", " (CO)", " (SCO)",
433     "", "", "", "",
434     " (ASR)", " (S, ASR)", " (CO, ASR)", " (SCO, ASR)",
435     " (ASL)", " (S, ASL)", " (CO, ASL)", " (SCO, ASL)",
436   };
437   int i = s0 + (x0 << 1) + (aop0 << 2);
438 
439   if (i < ARRAY_SIZE (mod02))
440     return mod02[i];
441   else
442     return "";
443 }
444 
445 static const char *
446 amod1 (int s0, int x0)
447 {
448   static const char * const mod1[] = {
449     " (NS)", " (S)",
450   };
451   int i = s0 + (x0 << 1);
452 
453   if (i < ARRAY_SIZE (mod1))
454     return mod1[i];
455   else
456     return "";
457 }
458 
459 static const char *
460 mac_optmode (int mmod, int MM)
461 {
462   static const char * const omode[] = {
463     [(M_S2RND << 1) + 0] = " (S2RND)",
464     [(M_T     << 1) + 0] = " (T)",
465     [(M_W32   << 1) + 0] = " (W32)",
466     [(M_FU    << 1) + 0] = " (FU)",
467     [(M_TFU   << 1) + 0] = " (TFU)",
468     [(M_IS    << 1) + 0] = " (IS)",
469     [(M_ISS2  << 1) + 0] = " (ISS2)",
470     [(M_IH    << 1) + 0] = " (IH)",
471     [(M_IU    << 1) + 0] = " (IU)",
472     [(M_S2RND << 1) + 1] = " (M, S2RND)",
473     [(M_T     << 1) + 1] = " (M, T)",
474     [(M_W32   << 1) + 1] = " (M, W32)",
475     [(M_FU    << 1) + 1] = " (M, FU)",
476     [(M_TFU   << 1) + 1] = " (M, TFU)",
477     [(M_IS    << 1) + 1] = " (M, IS)",
478     [(M_ISS2  << 1) + 1] = " (M, ISS2)",
479     [(M_IH    << 1) + 1] = " (M, IH)",
480     [(M_IU    << 1) + 1] = " (M, IU)",
481   };
482   int i = MM + (mmod << 1);
483 
484   if (i < ARRAY_SIZE (omode) && omode[i])
485     return omode[i];
486   else
487     return "";
488 }
489 
490 static const char *
491 get_store_name (SIM_CPU *cpu, bu32 *p)
492 {
493   if (p >= &DREG (0) && p <= &CYCLESREG)
494     return greg_names[p - &DREG (0)];
495   else if (p == &AXREG (0))
496     return greg_names[4 * 8 + 0];
497   else if (p == &AWREG (0))
498     return greg_names[4 * 8 + 1];
499   else if (p == &AXREG (1))
500     return greg_names[4 * 8 + 2];
501   else if (p == &AWREG (1))
502     return greg_names[4 * 8 + 3];
503   else if (p == &ASTATREG (av0))
504     return "ASTAT[av0]";
505   else if (p == &ASTATREG (av0s))
506     return "ASTAT[av0s]";
507   else if (p == &ASTATREG (av1))
508     return "ASTAT[av1]";
509   else if (p == &ASTATREG (av1s))
510     return "ASTAT[av1s]";
511   else if (p == &ASTATREG (v))
512     return "ASTAT[v]";
513   else if (p == &ASTATREG (vs))
514     return "ASTAT[vs]";
515   else if (p == &ASTATREG (v_copy))
516     return "ASTAT[v_copy]";
517   else if (p == &ASTATREG (az))
518     return "ASTAT[az]";
519   else if (p == &ASTATREG (an))
520     return "ASTAT[an]";
521   else if (p == &ASTATREG (az))
522     return "ASTAT[az]";
523   else if (p == &ASTATREG (ac0))
524     return "ASTAT[ac0]";
525   else if (p == &ASTATREG (ac0_copy))
526     return "ASTAT[ac0_copy]";
527   else
528     {
529       /* Worry about this when we start to STORE() it.  */
530       sim_io_eprintf (CPU_STATE (cpu), "STORE(): unknown register\n");
531       abort ();
532     }
533 }
534 
535 static void
536 queue_store (SIM_CPU *cpu, bu32 *addr, bu32 val)
537 {
538   struct store *s = &BFIN_CPU_STATE.stores[BFIN_CPU_STATE.n_stores];
539   s->addr = addr;
540   s->val = val;
541   TRACE_REGISTER (cpu, "queuing write %s = %#x",
542 		  get_store_name (cpu, addr), val);
543   ++BFIN_CPU_STATE.n_stores;
544 }
545 #define STORE(X, Y) \
546   do { \
547     if (BFIN_CPU_STATE.n_stores == 20) abort (); \
548     queue_store (cpu, &(X), (Y)); \
549   } while (0)
550 
551 static void
552 setflags_nz (SIM_CPU *cpu, bu32 val)
553 {
554   SET_ASTATREG (az, val == 0);
555   SET_ASTATREG (an, val >> 31);
556 }
557 
558 static void
559 setflags_nz_2x16 (SIM_CPU *cpu, bu32 val)
560 {
561   SET_ASTATREG (an, (bs16)val < 0 || (bs16)(val >> 16) < 0);
562   SET_ASTATREG (az, (bs16)val == 0 || (bs16)(val >> 16) == 0);
563 }
564 
565 static void
566 setflags_logical (SIM_CPU *cpu, bu32 val)
567 {
568   setflags_nz (cpu, val);
569   SET_ASTATREG (ac0, 0);
570   SET_ASTATREG (v, 0);
571 }
572 
573 static bu32
574 add_brev (bu32 addend1, bu32 addend2)
575 {
576   bu32 mask, b, r;
577   int i, cy;
578 
579   mask = 0x80000000;
580   r = 0;
581   cy = 0;
582 
583   for (i = 31; i >= 0; --i)
584     {
585       b = ((addend1 & mask) >> i) + ((addend2 & mask) >> i);
586       b += cy;
587       cy = b >> 1;
588       b &= 1;
589       r |= b << i;
590       mask >>= 1;
591     }
592 
593   return r;
594 }
595 
596 /* This is a bit crazy, but we want to simulate the hardware behavior exactly
597    rather than worry about the circular buffers being used correctly.  Which
598    isn't to say there isn't room for improvement here, just that we want to
599    be conservative.  See also dagsub().  */
600 static bu32
601 dagadd (SIM_CPU *cpu, int dagno, bs32 M)
602 {
603   bu64 i = IREG (dagno);
604   bu64 l = LREG (dagno);
605   bu64 b = BREG (dagno);
606   bu64 m = (bu32)M;
607 
608   bu64 LB, IM, IML;
609   bu32 im32, iml32, lb32, res;
610   bu64 msb, car;
611 
612   /* A naïve implementation that mostly works:
613   res = i + m;
614   if (l && res >= b + l)
615     res -= l;
616   STORE (IREG (dagno), res);
617    */
618 
619   msb = (bu64)1 << 31;
620   car = (bu64)1 << 32;
621 
622   IM = i + m;
623   im32 = IM;
624   LB = l + b;
625   lb32 = LB;
626 
627   if (M < 0)
628     {
629       IML = i + m + l;
630       iml32 = IML;
631       if ((i & msb) || (IM & car))
632 	res = (im32 < b) ? iml32 : im32;
633       else
634 	res = (im32 < b) ? im32 : iml32;
635     }
636   else
637     {
638       IML = i + m - l;
639       iml32 = IML;
640       if ((IM & car) == (LB & car))
641 	res = (im32 < lb32) ? im32 : iml32;
642       else
643 	res = (im32 < lb32) ? iml32 : im32;
644     }
645 
646   STORE (IREG (dagno), res);
647   return res;
648 }
649 
650 /* See dagadd() notes above.  */
651 static bu32
652 dagsub (SIM_CPU *cpu, int dagno, bs32 M)
653 {
654   bu64 i = IREG (dagno);
655   bu64 l = LREG (dagno);
656   bu64 b = BREG (dagno);
657   bu64 m = (bu32)M;
658 
659   bu64 mbar = (bu32)(~m + 1);
660   bu64 LB, IM, IML;
661   bu32 b32, im32, iml32, lb32, res;
662   bu64 msb, car;
663 
664   /* A naïve implementation that mostly works:
665   res = i - m;
666   if (l && newi < b)
667     newi += l;
668   STORE (IREG (dagno), newi);
669    */
670 
671   msb = (bu64)1 << 31;
672   car = (bu64)1 << 32;
673 
674   IM = i + mbar;
675   im32 = IM;
676   LB = l + b;
677   lb32 = LB;
678 
679   if (M < 0)
680     {
681       IML = i + mbar - l;
682       iml32 = IML;
683       if (!!((i & msb) && (IM & car)) == !!(LB & car))
684 	res = (im32 < lb32) ? im32 : iml32;
685       else
686 	res = (im32 < lb32) ? iml32 : im32;
687     }
688   else
689     {
690       IML = i + mbar + l;
691       iml32 = IML;
692       b32 = b;
693       if (M == 0 || IM & car)
694 	res = (im32 < b32) ? iml32 : im32;
695       else
696 	res = (im32 < b32) ? im32 : iml32;
697     }
698 
699   STORE (IREG (dagno), res);
700   return res;
701 }
702 
703 static bu40
704 ashiftrt (SIM_CPU *cpu, bu40 val, int cnt, int size)
705 {
706   int real_cnt = cnt > size ? size : cnt;
707   bu40 sgn = ~(((val & 0xFFFFFFFFFFull) >> (size - 1)) - 1);
708   int sgncnt = size - real_cnt;
709   if (sgncnt > 16)
710     sgn <<= 16, sgncnt -= 16;
711   sgn <<= sgncnt;
712   if (real_cnt > 16)
713     val >>= 16, real_cnt -= 16;
714   val >>= real_cnt;
715   val |= sgn;
716   SET_ASTATREG (an, val >> (size - 1));
717   SET_ASTATREG (az, val == 0);
718   if (size != 40)
719     SET_ASTATREG (v, 0);
720   return val;
721 }
722 
723 static bu64
724 lshiftrt (SIM_CPU *cpu, bu64 val, int cnt, int size)
725 {
726   int real_cnt = cnt > size ? size : cnt;
727   if (real_cnt > 16)
728     val >>= 16, real_cnt -= 16;
729   val >>= real_cnt;
730   switch (size)
731     {
732     case 16:
733       val &= 0xFFFF;
734       break;
735     case 32:
736       val &= 0xFFFFFFFF;
737       break;
738     case 40:
739       val &= 0xFFFFFFFFFFull;
740       break;
741     default:
742       illegal_instruction (cpu);
743       break;
744     }
745   SET_ASTATREG (an, val >> (size - 1));
746   SET_ASTATREG (az, val == 0);
747   if (size != 40)
748     SET_ASTATREG (v, 0);
749   return val;
750 }
751 
752 static bu64
753 lshift (SIM_CPU *cpu, bu64 val, int cnt, int size, bool saturate, bool overflow)
754 {
755   int v_i, real_cnt = cnt > size ? size : cnt;
756   bu64 sgn = ~((val >> (size - 1)) - 1);
757   int mask_cnt = size - 1;
758   bu64 masked, new_val = val;
759   bu64 mask = ~0;
760 
761   mask <<= mask_cnt;
762   sgn <<= mask_cnt;
763   masked = val & mask;
764 
765   if (real_cnt > 16)
766     new_val <<= 16, real_cnt -= 16;
767 
768   new_val <<= real_cnt;
769 
770   masked = new_val & mask;
771 
772   /* If an operation would otherwise cause a positive value to overflow
773      and become negative, instead, saturation limits the result to the
774      maximum positive value for the size register being used.
775 
776      Conversely, if an operation would otherwise cause a negative value
777      to overflow and become positive, saturation limits the result to the
778      maximum negative value for the register size.
779 
780      However, it's a little more complex than looking at sign bits, we need
781      to see if we are shifting the sign information away...  */
782   if (((val << cnt) >> size) == 0
783       || (((val << cnt) >> size) == ~(~0 << cnt)
784 	  && ((new_val >> (size - 1)) & 0x1)))
785     v_i = 0;
786   else
787     v_i = 1;
788 
789   switch (size)
790     {
791     case 16:
792       new_val &= 0xFFFF;
793       if (saturate && (v_i || ((val >> (size - 1)) != (new_val >> (size - 1)))))
794 	{
795 	  new_val = (val >> (size - 1)) == 0 ? 0x7fff : 0x8000;
796 	  v_i = 1;
797 	}
798       break;
799     case 32:
800       new_val &= 0xFFFFFFFF;
801       masked &= 0xFFFFFFFF;
802       sgn &= 0xFFFFFFFF;
803       if (saturate
804 	  && (v_i
805 	      || (sgn != masked)
806 	      || (!sgn && new_val == 0 && val != 0)))
807 	{
808 	  new_val = sgn == 0 ? 0x7fffffff : 0x80000000;
809 	  v_i = 1;
810 	}
811       break;
812     case 40:
813       new_val &= 0xFFFFFFFFFFull;
814       masked &= 0xFFFFFFFFFFull;
815       break;
816     default:
817       illegal_instruction (cpu);
818       break;
819     }
820 
821   SET_ASTATREG (an, new_val >> (size - 1));
822   SET_ASTATREG (az, new_val == 0);
823   if (size != 40)
824     {
825       SET_ASTATREG (v, overflow && v_i);
826       if (overflow && v_i)
827 	SET_ASTATREG (vs, 1);
828     }
829 
830   return new_val;
831 }
832 
833 static bu32
834 algn (bu32 l, bu32 h, bu32 aln)
835 {
836   if (aln == 0)
837     return l;
838   else
839     return (l >> (8 * aln)) | (h << (32 - 8 * aln));
840 }
841 
842 static bu32
843 saturate_s16 (bu64 val, bu32 *overflow)
844 {
845   if ((bs64)val < -0x8000ll)
846     {
847       if (overflow)
848 	*overflow = 1;
849       return 0x8000;
850     }
851   if ((bs64)val > 0x7fff)
852     {
853       if (overflow)
854 	*overflow = 1;
855       return 0x7fff;
856     }
857   return val & 0xffff;
858 }
859 
860 static bu40
861 rot40 (bu40 val, int shift, bu32 *cc)
862 {
863   const int nbits = 40;
864   bu40 ret;
865 
866   shift = CLAMP (shift, -nbits, nbits);
867   if (shift == 0)
868     return val;
869 
870   /* Reduce everything to rotate left.  */
871   if (shift < 0)
872     shift += nbits + 1;
873 
874   ret = shift == nbits ? 0 : val << shift;
875   ret |= shift == 1 ? 0 : val >> ((nbits + 1) - shift);
876   ret |= (bu40)*cc << (shift - 1);
877   *cc = (val >> (nbits - shift)) & 1;
878 
879   return ret;
880 }
881 
882 static bu32
883 rot32 (bu32 val, int shift, bu32 *cc)
884 {
885   const int nbits = 32;
886   bu32 ret;
887 
888   shift = CLAMP (shift, -nbits, nbits);
889   if (shift == 0)
890     return val;
891 
892   /* Reduce everything to rotate left.  */
893   if (shift < 0)
894     shift += nbits + 1;
895 
896   ret = shift == nbits ? 0 : val << shift;
897   ret |= shift == 1 ? 0 : val >> ((nbits + 1) - shift);
898   ret |= (bu32)*cc << (shift - 1);
899   *cc = (val >> (nbits - shift)) & 1;
900 
901   return ret;
902 }
903 
904 static bu32
905 add32 (SIM_CPU *cpu, bu32 a, bu32 b, int carry, int sat)
906 {
907   int flgs = (a >> 31) & 1;
908   int flgo = (b >> 31) & 1;
909   bu32 v = a + b;
910   int flgn = (v >> 31) & 1;
911   int overflow = (flgs ^ flgn) & (flgo ^ flgn);
912 
913   if (sat && overflow)
914     {
915       v = (bu32)1 << 31;
916       if (flgn)
917 	v -= 1;
918       flgn = (v >> 31) & 1;
919     }
920 
921   SET_ASTATREG (an, flgn);
922   if (overflow)
923     SET_ASTATREG (vs, 1);
924   SET_ASTATREG (v, overflow);
925   ASTATREG (v_internal) |= overflow;
926   SET_ASTATREG (az, v == 0);
927   if (carry)
928     SET_ASTATREG (ac0, ~a < b);
929 
930   return v;
931 }
932 
933 static bu32
934 sub32 (SIM_CPU *cpu, bu32 a, bu32 b, int carry, int sat, int parallel)
935 {
936   int flgs = (a >> 31) & 1;
937   int flgo = (b >> 31) & 1;
938   bu32 v = a - b;
939   int flgn = (v >> 31) & 1;
940   int overflow = (flgs ^ flgo) & (flgn ^ flgs);
941 
942   if (sat && overflow)
943     {
944       v = (bu32)1 << 31;
945       if (flgn)
946 	v -= 1;
947       flgn = (v >> 31) & 1;
948     }
949 
950   if (!parallel || flgn)
951     SET_ASTATREG (an, flgn);
952   if (overflow)
953     SET_ASTATREG (vs, 1);
954   if (!parallel || overflow)
955     SET_ASTATREG (v, overflow);
956   if (!parallel || overflow)
957     ASTATREG (v_internal) |= overflow;
958   if (!parallel || v == 0)
959     SET_ASTATREG (az, v == 0);
960   if (carry && (!parallel || b <= a))
961     SET_ASTATREG (ac0, b <= a);
962 
963   return v;
964 }
965 
966 static bu32
967 add16 (SIM_CPU *cpu, bu16 a, bu16 b, bu32 *carry, bu32 *overfl,
968        bu32 *zero, bu32 *neg, int sat, int scale)
969 {
970   int flgs = (a >> 15) & 1;
971   int flgo = (b >> 15) & 1;
972   bs64 v = (bs16)a + (bs16)b;
973   int flgn = (v >> 15) & 1;
974   int overflow = (flgs ^ flgn) & (flgo ^ flgn);
975 
976   switch (scale)
977     {
978     case 0:
979       break;
980     case 2:
981       /* (ASR)  */
982       v = (a >> 1) + (a & 0x8000) + (b >> 1) + (b & 0x8000)
983 	  + (((a & 1) + (b & 1)) >> 1);
984       v |= -(v & 0x8000);
985       break;
986     case 3:
987       /* (ASL)  */
988       v = (v << 1);
989       break;
990     default:
991       illegal_instruction (cpu);
992     }
993 
994   flgn = (v >> 15) & 1;
995   overflow = (flgs ^ flgn) & (flgo ^ flgn);
996 
997   if (v > (bs64)0xffff)
998     overflow = 1;
999 
1000   if (sat)
1001     v = saturate_s16 (v, 0);
1002 
1003   if (neg)
1004     *neg |= (v >> 15) & 1;
1005   if (overfl)
1006     *overfl |= overflow;
1007   if (zero)
1008     *zero |= (v & 0xFFFF) == 0;
1009   if (carry)
1010       *carry |= ((bu16)~a < (bu16)b);
1011 
1012   return v & 0xffff;
1013 }
1014 
1015 static bu32
1016 sub16 (SIM_CPU *cpu, bu16 a, bu16 b, bu32 *carry, bu32 *overfl,
1017        bu32 *zero, bu32 *neg, int sat, int scale)
1018 {
1019   int flgs = (a >> 15) & 1;
1020   int flgo = (b >> 15) & 1;
1021   bs64 v = (bs16)a - (bs16)b;
1022   int flgn = (v >> 15) & 1;
1023   int overflow = (flgs ^ flgo) & (flgn ^ flgs);
1024 
1025   switch (scale)
1026     {
1027     case 0:
1028       break;
1029     case 2:
1030       /* (ASR)  */
1031       if (sat)
1032 	v = ((a >> 1) + (a & 0x8000)) - ( (b >> 1) + (b & 0x8000))
1033 	    + (((a & 1)-(b & 1)));
1034       else
1035 	{
1036 	  v = ((v & 0xFFFF) >> 1);
1037 	  if ((!flgs & !flgo & flgn)
1038 	      || (flgs & !flgo & !flgn)
1039 	      || (flgs & flgo & flgn)
1040 	      || (flgs & !flgo & flgn))
1041 	    v |= 0x8000;
1042 	}
1043       v |= -(v & 0x8000);
1044       flgn = (v >> 15) & 1;
1045       overflow = (flgs ^ flgo) & (flgn ^ flgs);
1046       break;
1047     case 3:
1048       /* (ASL)  */
1049       v <<= 1;
1050       if (v > (bs64)0x7fff || v < (bs64)-0xffff)
1051 	overflow = 1;
1052       break;
1053     default:
1054       illegal_instruction (cpu);
1055     }
1056 
1057   if (sat)
1058     {
1059       v = saturate_s16 (v, 0);
1060     }
1061   if (neg)
1062     *neg |= (v >> 15) & 1;
1063   if (zero)
1064     *zero |= (v & 0xFFFF) == 0;
1065   if (overfl)
1066     *overfl |= overflow;
1067   if (carry)
1068     *carry |= (bu16)b <= (bu16)a;
1069   return v;
1070 }
1071 
1072 static bu32
1073 min32 (SIM_CPU *cpu, bu32 a, bu32 b)
1074 {
1075   int val = a;
1076   if ((bs32)a > (bs32)b)
1077     val = b;
1078   setflags_nz (cpu, val);
1079   SET_ASTATREG (v, 0);
1080   return val;
1081 }
1082 
1083 static bu32
1084 max32 (SIM_CPU *cpu, bu32 a, bu32 b)
1085 {
1086   int val = a;
1087   if ((bs32)a < (bs32)b)
1088     val = b;
1089   setflags_nz (cpu, val);
1090   SET_ASTATREG (v, 0);
1091   return val;
1092 }
1093 
1094 static bu32
1095 min2x16 (SIM_CPU *cpu, bu32 a, bu32 b)
1096 {
1097   int val = a;
1098   if ((bs16)a > (bs16)b)
1099     val = (val & 0xFFFF0000) | (b & 0xFFFF);
1100   if ((bs16)(a >> 16) > (bs16)(b >> 16))
1101     val = (val & 0xFFFF) | (b & 0xFFFF0000);
1102   setflags_nz_2x16 (cpu, val);
1103   SET_ASTATREG (v, 0);
1104   return val;
1105 }
1106 
1107 static bu32
1108 max2x16 (SIM_CPU *cpu, bu32 a, bu32 b)
1109 {
1110   int val = a;
1111   if ((bs16)a < (bs16)b)
1112     val = (val & 0xFFFF0000) | (b & 0xFFFF);
1113   if ((bs16)(a >> 16) < (bs16)(b >> 16))
1114     val = (val & 0xFFFF) | (b & 0xFFFF0000);
1115   setflags_nz_2x16 (cpu, val);
1116   SET_ASTATREG (v, 0);
1117   return val;
1118 }
1119 
1120 static bu32
1121 add_and_shift (SIM_CPU *cpu, bu32 a, bu32 b, int shift)
1122 {
1123   int v;
1124   ASTATREG (v_internal) = 0;
1125   v = add32 (cpu, a, b, 0, 0);
1126   while (shift-- > 0)
1127     {
1128       int x = (v >> 30) & 0x3;
1129       if (x == 1 || x == 2)
1130 	ASTATREG (v_internal) = 1;
1131       v <<= 1;
1132     }
1133   SET_ASTATREG (az, v == 0);
1134   SET_ASTATREG (an, v & 0x80000000);
1135   SET_ASTATREG (v, ASTATREG (v_internal));
1136   if (ASTATREG (v))
1137     SET_ASTATREG (vs, 1);
1138   return v;
1139 }
1140 
1141 static bu32
1142 xor_reduce (bu64 acc0, bu64 acc1)
1143 {
1144   int i;
1145   bu32 v = 0;
1146   for (i = 0; i < 40; ++i)
1147     {
1148       v ^= (acc0 & acc1 & 1);
1149       acc0 >>= 1;
1150       acc1 >>= 1;
1151     }
1152   return v;
1153 }
1154 
1155 /* DIVS ( Dreg, Dreg ) ;
1156    Initialize for DIVQ.  Set the AQ status bit based on the signs of
1157    the 32-bit dividend and the 16-bit divisor.  Left shift the dividend
1158    one bit.  Copy AQ into the dividend LSB.  */
1159 static bu32
1160 divs (SIM_CPU *cpu, bu32 pquo, bu16 divisor)
1161 {
1162   bu16 r = pquo >> 16;
1163   int aq;
1164 
1165   aq = (r ^ divisor) >> 15;  /* Extract msb's and compute quotient bit.  */
1166   SET_ASTATREG (aq, aq);     /* Update global quotient state.  */
1167 
1168   pquo <<= 1;
1169   pquo |= aq;
1170   pquo = (pquo & 0x1FFFF) | (r << 17);
1171   return pquo;
1172 }
1173 
1174 /* DIVQ ( Dreg, Dreg ) ;
1175    Based on AQ status bit, either add or subtract the divisor from
1176    the dividend.  Then set the AQ status bit based on the MSBs of the
1177    32-bit dividend and the 16-bit divisor.  Left shift the dividend one
1178    bit.  Copy the logical inverse of AQ into the dividend LSB.  */
1179 static bu32
1180 divq (SIM_CPU *cpu, bu32 pquo, bu16 divisor)
1181 {
1182   unsigned short af = pquo >> 16;
1183   unsigned short r;
1184   int aq;
1185 
1186   if (ASTATREG (aq))
1187     r = divisor + af;
1188   else
1189     r = af - divisor;
1190 
1191   aq = (r ^ divisor) >> 15;  /* Extract msb's and compute quotient bit.  */
1192   SET_ASTATREG (aq, aq);     /* Update global quotient state.  */
1193 
1194   pquo <<= 1;
1195   pquo |= !aq;
1196   pquo = (pquo & 0x1FFFF) | (r << 17);
1197   return pquo;
1198 }
1199 
1200 /* ONES ( Dreg ) ;
1201    Count the number of bits set to 1 in the 32bit value.  */
1202 static bu32
1203 ones (bu32 val)
1204 {
1205   bu32 i;
1206   bu32 ret;
1207 
1208   ret = 0;
1209   for (i = 0; i < 32; ++i)
1210     ret += !!(val & (1 << i));
1211 
1212   return ret;
1213 }
1214 
1215 static void
1216 reg_check_sup (SIM_CPU *cpu, int grp, int reg)
1217 {
1218   if (grp == 7)
1219     cec_require_supervisor (cpu);
1220 }
1221 
1222 static void
1223 reg_write (SIM_CPU *cpu, int grp, int reg, bu32 value)
1224 {
1225   bu32 *whichreg;
1226 
1227   /* ASTAT is special!  */
1228   if (grp == 4 && reg == 6)
1229     {
1230       SET_ASTAT (value);
1231       return;
1232     }
1233 
1234   /* Check supervisor after get_allreg() so exception order is correct.  */
1235   whichreg = get_allreg (cpu, grp, reg);
1236   reg_check_sup (cpu, grp, reg);
1237 
1238   if (whichreg == &CYCLES2REG)
1239     /* Writes to CYCLES2 goes to the shadow.  */
1240     whichreg = &CYCLES2SHDREG;
1241   else if (whichreg == &SEQSTATREG)
1242     /* Register is read only -- discard writes.  */
1243     return;
1244   else if (whichreg == &EMUDAT_INREG)
1245     /* Writes to EMUDAT goes to the output.  */
1246     whichreg = &EMUDAT_OUTREG;
1247   else if (whichreg == &LTREG (0) || whichreg == &LTREG (1))
1248     /* Writes to LT clears LSB automatically.  */
1249     value &= ~0x1;
1250   else if (whichreg == &AXREG (0) || whichreg == &AXREG (1))
1251     value &= 0xFF;
1252 
1253   TRACE_REGISTER (cpu, "wrote %s = %#x", get_allreg_name (grp, reg), value);
1254 
1255   *whichreg = value;
1256 }
1257 
1258 static bu32
1259 reg_read (SIM_CPU *cpu, int grp, int reg)
1260 {
1261   bu32 *whichreg;
1262   bu32 value;
1263 
1264   /* ASTAT is special!  */
1265   if (grp == 4 && reg == 6)
1266     return ASTAT;
1267 
1268   /* Check supervisor after get_allreg() so exception order is correct.  */
1269   whichreg = get_allreg (cpu, grp, reg);
1270   reg_check_sup (cpu, grp, reg);
1271 
1272   value = *whichreg;
1273 
1274   if (whichreg == &CYCLESREG)
1275     /* Reads of CYCLES reloads CYCLES2 from the shadow.  */
1276     SET_CYCLES2REG (CYCLES2SHDREG);
1277   else if ((whichreg == &AXREG (1) || whichreg == &AXREG (0)) && (value & 0x80))
1278     /* Sign extend if necessary.  */
1279     value |= 0xFFFFFF00;
1280 
1281   return value;
1282 }
1283 
1284 static bu64
1285 get_extended_cycles (SIM_CPU *cpu)
1286 {
1287   return ((bu64)CYCLES2SHDREG << 32) | CYCLESREG;
1288 }
1289 
1290 /* We can't re-use sim_events_time() because the CYCLES registers may be
1291    written/cleared/reset/stopped/started at any time by software.  */
1292 static void
1293 cycles_inc (SIM_CPU *cpu, bu32 inc)
1294 {
1295   bu64 cycles;
1296   bu32 cycles2;
1297 
1298   if (!(SYSCFGREG & SYSCFG_CCEN))
1299     return;
1300 
1301   cycles = get_extended_cycles (cpu) + inc;
1302   SET_CYCLESREG (cycles);
1303   cycles2 = cycles >> 32;
1304   if (CYCLES2SHDREG != cycles2)
1305     SET_CYCLES2SHDREG (cycles2);
1306 }
1307 
1308 static bu64
1309 get_unextended_acc (SIM_CPU *cpu, int which)
1310 {
1311   return ((bu64)(AXREG (which) & 0xff) << 32) | AWREG (which);
1312 }
1313 
1314 static bu64
1315 get_extended_acc (SIM_CPU *cpu, int which)
1316 {
1317   bu64 acc = AXREG (which);
1318   /* Sign extend accumulator values before adding.  */
1319   if (acc & 0x80)
1320     acc |= -0x80;
1321   else
1322     acc &= 0xFF;
1323   acc <<= 32;
1324   acc |= AWREG (which);
1325   return acc;
1326 }
1327 
1328 /* Perform a multiplication of D registers SRC0 and SRC1, sign- or
1329    zero-extending the result to 64 bit.  H0 and H1 determine whether the
1330    high part or the low part of the source registers is used.  Store 1 in
1331    *PSAT if saturation occurs, 0 otherwise.  */
1332 static bu64
1333 decode_multfunc (SIM_CPU *cpu, int h0, int h1, int src0, int src1, int mmod,
1334 		 int MM, bu32 *psat)
1335 {
1336   bu32 s0 = DREG (src0), s1 = DREG (src1);
1337   bu32 sgn0, sgn1;
1338   bu32 val;
1339   bu64 val1;
1340 
1341   if (h0)
1342     s0 >>= 16;
1343 
1344   if (h1)
1345     s1 >>= 16;
1346 
1347   s0 &= 0xffff;
1348   s1 &= 0xffff;
1349 
1350   sgn0 = -(s0 & 0x8000);
1351   sgn1 = -(s1 & 0x8000);
1352 
1353   if (MM)
1354     s0 |= sgn0;
1355   else
1356     switch (mmod)
1357       {
1358       case 0:
1359       case M_S2RND:
1360       case M_T:
1361       case M_IS:
1362       case M_ISS2:
1363       case M_IH:
1364       case M_W32:
1365 	s0 |= sgn0;
1366 	s1 |= sgn1;
1367 	break;
1368       case M_FU:
1369       case M_IU:
1370       case M_TFU:
1371 	break;
1372       default:
1373 	illegal_instruction (cpu);
1374       }
1375 
1376   val = s0 * s1;
1377   /* Perform shift correction if appropriate for the mode.  */
1378   *psat = 0;
1379   if (!MM && (mmod == 0 || mmod == M_T || mmod == M_S2RND || mmod == M_W32))
1380     {
1381       if (val == 0x40000000)
1382 	{
1383 	  if (mmod == M_W32)
1384 	    val = 0x7fffffff;
1385 	  else
1386 	    val = 0x80000000;
1387 	  *psat = 1;
1388 	}
1389       else
1390 	val <<= 1;
1391     }
1392   val1 = val;
1393 
1394   /* In signed modes, sign extend.  */
1395   if (is_macmod_signed (mmod) || MM)
1396     val1 |= -(val1 & 0x80000000);
1397 
1398   if (*psat)
1399     val1 &= 0xFFFFFFFFull;
1400 
1401   return val1;
1402 }
1403 
1404 static bu40
1405 saturate_s40_astat (bu64 val, bu32 *v)
1406 {
1407   if ((bs64)val < -((bs64)1 << 39))
1408     {
1409       *v = 1;
1410       return -((bs64)1 << 39);
1411     }
1412   else if ((bs64)val > ((bs64)1 << 39) - 1)
1413     {
1414       *v = 1;
1415       return ((bu64)1 << 39) - 1;
1416     }
1417   *v = 0; /* No overflow.  */
1418   return val;
1419 }
1420 
1421 static bu40
1422 saturate_s40 (bu64 val)
1423 {
1424   bu32 v;
1425   return saturate_s40_astat (val, &v);
1426 }
1427 
1428 static bu32
1429 saturate_s32 (bu64 val, bu32 *overflow)
1430 {
1431   if ((bs64)val < -0x80000000ll)
1432     {
1433       if (overflow)
1434 	*overflow = 1;
1435       return 0x80000000;
1436     }
1437   if ((bs64)val > 0x7fffffff)
1438     {
1439       if (overflow)
1440 	*overflow = 1;
1441       return 0x7fffffff;
1442     }
1443   return val;
1444 }
1445 
1446 static bu32
1447 saturate_u32 (bu64 val, bu32 *overflow)
1448 {
1449   if (val > 0xffffffff)
1450     {
1451       if (overflow)
1452 	*overflow = 1;
1453       return 0xffffffff;
1454     }
1455   return val;
1456 }
1457 
1458 static bu32
1459 saturate_u16 (bu64 val, bu32 *overflow)
1460 {
1461   if (val > 0xffff)
1462     {
1463       if (overflow)
1464 	*overflow = 1;
1465       return 0xffff;
1466     }
1467   return val;
1468 }
1469 
1470 static bu64
1471 rnd16 (bu64 val)
1472 {
1473   bu64 sgnbits;
1474 
1475   /* FIXME: Should honour rounding mode.  */
1476   if ((val & 0xffff) > 0x8000
1477       || ((val & 0xffff) == 0x8000 && (val & 0x10000)))
1478     val += 0x8000;
1479 
1480   sgnbits = val & 0xffff000000000000ull;
1481   val >>= 16;
1482   return val | sgnbits;
1483 }
1484 
1485 static bu64
1486 trunc16 (bu64 val)
1487 {
1488   bu64 sgnbits = val & 0xffff000000000000ull;
1489   val >>= 16;
1490   return val | sgnbits;
1491 }
1492 
1493 static int
1494 signbits (bu64 val, int size)
1495 {
1496   bu64 mask = (bu64)1 << (size - 1);
1497   bu64 bit = val & mask;
1498   int count = 0;
1499   for (;;)
1500     {
1501       mask >>= 1;
1502       bit >>= 1;
1503       if (mask == 0)
1504 	break;
1505       if ((val & mask) != bit)
1506 	break;
1507       count++;
1508     }
1509   if (size == 40)
1510     count -= 8;
1511 
1512   return count;
1513 }
1514 
1515 /* Extract a 16 or 32 bit value from a 64 bit multiplication result.
1516    These 64 bits must be sign- or zero-extended properly from the source
1517    we want to extract, either a 32 bit multiply or a 40 bit accumulator.  */
1518 
1519 static bu32
1520 extract_mult (SIM_CPU *cpu, bu64 res, int mmod, int MM,
1521 	      int fullword, bu32 *overflow)
1522 {
1523   if (fullword)
1524     switch (mmod)
1525       {
1526       case 0:
1527       case M_IS:
1528 	return saturate_s32 (res, overflow);
1529       case M_IU:
1530 	if (MM)
1531 	  return saturate_s32 (res, overflow);
1532 	return saturate_u32 (res, overflow);
1533       case M_FU:
1534 	if (MM)
1535 	  return saturate_s32 (res, overflow);
1536 	return saturate_u32 (res, overflow);
1537       case M_S2RND:
1538       case M_ISS2:
1539 	return saturate_s32 (res << 1, overflow);
1540       default:
1541 	illegal_instruction (cpu);
1542       }
1543   else
1544     switch (mmod)
1545       {
1546       case 0:
1547       case M_W32:
1548       case M_IH:
1549 	return saturate_s16 (rnd16 (res), overflow);
1550       case M_IS:
1551 	return saturate_s16 (res, overflow);
1552       case M_FU:
1553 	if (MM)
1554 	  return saturate_s16 (rnd16 (res), overflow);
1555 	return saturate_u16 (rnd16 (res), overflow);
1556       case M_IU:
1557 	if (MM)
1558 	  return saturate_s16 (res, overflow);
1559 	return saturate_u16 (res, overflow);
1560 
1561       case M_T:
1562 	return saturate_s16 (trunc16 (res), overflow);
1563       case M_TFU:
1564 	if (MM)
1565 	  return saturate_s16 (trunc16 (res), overflow);
1566 	return saturate_u16 (trunc16 (res), overflow);
1567 
1568       case M_S2RND:
1569 	return saturate_s16 (rnd16 (res << 1), overflow);
1570       case M_ISS2:
1571 	return saturate_s16 (res << 1, overflow);
1572       default:
1573 	illegal_instruction (cpu);
1574       }
1575 }
1576 
1577 static bu32
1578 decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
1579 		int src1, int mmod, int MM, int fullword, bu32 *overflow,
1580 		bu32 *neg)
1581 {
1582   bu64 acc;
1583   bu32 sat = 0, tsat, ret;
1584 
1585   /* Sign extend accumulator if necessary, otherwise unsigned.  */
1586   if (is_macmod_signed (mmod) || MM)
1587     acc = get_extended_acc (cpu, which);
1588   else
1589     acc = get_unextended_acc (cpu, which);
1590 
1591   if (op != 3)
1592     {
1593       bu8 sgn0 = (acc >> 31) & 1;
1594       bu8 sgn40 = (acc >> 39) & 1;
1595       bu40 nosat_acc;
1596 
1597       /* This can't saturate, so we don't keep track of the sat flag.  */
1598       bu64 res = decode_multfunc (cpu, h0, h1, src0, src1, mmod,
1599 				  MM, &tsat);
1600 
1601       /* Perform accumulation.  */
1602       switch (op)
1603 	{
1604 	case 0:
1605 	  acc = res;
1606 	  sgn0 = (acc >> 31) & 1;
1607 	  break;
1608 	case 1:
1609 	  acc = acc + res;
1610 	  break;
1611 	case 2:
1612 	  acc = acc - res;
1613 	  break;
1614 	}
1615 
1616       nosat_acc = acc;
1617       /* Saturate.  */
1618       switch (mmod)
1619 	{
1620 	case 0:
1621 	case M_T:
1622 	case M_IS:
1623 	case M_ISS2:
1624 	case M_S2RND:
1625 	  if ((bs64)acc < -((bs64)1 << 39))
1626 	    acc = -((bu64)1 << 39), sat = 1;
1627 	  else if ((bs64)acc > 0x7fffffffffll)
1628 	    acc = 0x7fffffffffull, sat = 1;
1629 	  break;
1630 	case M_TFU:
1631 	  if (MM)
1632 	    {
1633 	      if ((bs64)acc < -((bs64)1 << 39))
1634 		acc = -((bu64)1 << 39), sat = 1;
1635 	      if ((bs64)acc > 0x7FFFFFFFFFll)
1636 		acc = 0x7FFFFFFFFFull, sat = 1;
1637 	    }
1638 	  else
1639 	    {
1640 	      if ((bs64)acc < 0)
1641 		acc = 0, sat = 1;
1642 	      if ((bs64)acc > 0xFFFFFFFFFFull)
1643 		acc = 0xFFFFFFFFFFull, sat = 1;
1644 	    }
1645 	  break;
1646 	case M_IU:
1647 	  if (!MM && acc & 0x8000000000000000ull)
1648 	    acc = 0x0, sat = 1;
1649 	  if (!MM && acc > 0xFFFFFFFFFFull)
1650 	    acc = 0xFFFFFFFFFFull, sat = 1;
1651 	  if (MM && acc > 0xFFFFFFFFFFull)
1652 	    acc &= 0xFFFFFFFFFFull;
1653 	  if (acc & 0x8000000000ull)
1654 	    acc |= 0xffffff0000000000ull;
1655 	  break;
1656 	case M_FU:
1657 	  if (MM)
1658 	    {
1659 	      if ((bs64)acc < -((bs64)1 << 39))
1660 		acc = -((bu64)1 << 39), sat = 1;
1661 	      if ((bs64)acc > 0x7FFFFFFFFFll)
1662 		acc = 0x7FFFFFFFFFull, sat = 1;
1663 	      else if (acc & 0x8000000000ull)
1664 		acc |= 0xffffff0000000000ull;
1665 	    }
1666 	  else
1667 	    {
1668 	      if ((bs64)acc < 0)
1669 		acc = 0x0, sat = 1;
1670 	      else if ((bs64)acc > (bs64)0xFFFFFFFFFFll)
1671 		acc = 0xFFFFFFFFFFull, sat = 1;
1672 	    }
1673 	  break;
1674 	case M_IH:
1675 	  if ((bs64)acc < -0x80000000ll)
1676 	    acc = -0x80000000ull, sat = 1;
1677 	  else if ((bs64)acc > 0x7fffffffll)
1678 	    acc = 0x7fffffffull, sat = 1;
1679 	  break;
1680 	case M_W32:
1681 	  /* check max negative value */
1682 	  if (sgn40 && ((acc >> 31) != 0x1ffffffff)
1683 	      && ((acc >> 31) != 0x0))
1684 	    acc = 0x80000000, sat = 1;
1685 	  if (!sat && !sgn40 && ((acc >> 31) != 0x0)
1686 	      && ((acc >> 31) != 0x1ffffffff))
1687 	    acc = 0x7FFFFFFF, sat = 1;
1688 	  acc &= 0xffffffff;
1689 	  if (acc & 0x80000000)
1690 	    acc |= 0xffffffff00000000ull;
1691 	  if (tsat)
1692 	    sat = 1;
1693 	  break;
1694 	default:
1695 	  illegal_instruction (cpu);
1696 	}
1697 
1698       if (acc & 0x8000000000ull)
1699 	*neg = 1;
1700 
1701       STORE (AXREG (which), (acc >> 32) & 0xff);
1702       STORE (AWREG (which), acc & 0xffffffff);
1703       STORE (ASTATREG (av[which]), sat);
1704       if (sat)
1705 	STORE (ASTATREG (avs[which]), sat);
1706 
1707       /* Figure out the overflow bit.  */
1708       if (sat)
1709 	{
1710 	  if (fullword)
1711 	    *overflow = 1;
1712 	  else
1713 	    ret = extract_mult (cpu, nosat_acc, mmod, MM, fullword, overflow);
1714 	}
1715     }
1716 
1717   ret = extract_mult (cpu, acc, mmod, MM, fullword, overflow);
1718 
1719   if (!fullword)
1720     {
1721       if (ret & 0x8000)
1722 	*neg = 1;
1723     }
1724   else
1725     {
1726       if (ret & 0x80000000)
1727 	*neg = 1;
1728     }
1729 
1730   return ret;
1731 }
1732 
1733 bu32
1734 hwloop_get_next_pc (SIM_CPU *cpu, bu32 pc, bu32 insn_len)
1735 {
1736   int i;
1737 
1738   if (insn_len == 0)
1739     return pc;
1740 
1741   /* If our PC has reached the bottom of a hardware loop,
1742      move back up to the top of the hardware loop.  */
1743   for (i = 1; i >= 0; --i)
1744     if (LCREG (i) > 1 && pc == LBREG (i))
1745       {
1746 	BFIN_TRACE_BRANCH (cpu, pc, LTREG (i), i, "Hardware loop %i", i);
1747 	return LTREG (i);
1748       }
1749 
1750   return pc + insn_len;
1751 }
1752 
1753 static void
1754 decode_ProgCtrl_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc)
1755 {
1756   /* ProgCtrl
1757      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
1758      | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.prgfunc.......|.poprnd........|
1759      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
1760   int poprnd  = ((iw0 >> ProgCtrl_poprnd_bits) & ProgCtrl_poprnd_mask);
1761   int prgfunc = ((iw0 >> ProgCtrl_prgfunc_bits) & ProgCtrl_prgfunc_mask);
1762 
1763   TRACE_EXTRACT (cpu, "%s: poprnd:%i prgfunc:%i", __func__, poprnd, prgfunc);
1764 
1765   if (prgfunc == 0 && poprnd == 0)
1766     {
1767       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_nop);
1768       TRACE_INSN (cpu, "NOP;");
1769     }
1770   else if (prgfunc == 1 && poprnd == 0)
1771     {
1772       bu32 newpc = RETSREG;
1773       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1774       TRACE_INSN (cpu, "RTS;");
1775       IFETCH_CHECK (newpc);
1776       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1777 	illegal_instruction_combination (cpu);
1778       BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "RTS");
1779       SET_PCREG (newpc);
1780       BFIN_CPU_STATE.did_jump = true;
1781       CYCLE_DELAY = 5;
1782     }
1783   else if (prgfunc == 1 && poprnd == 1)
1784     {
1785       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1786       TRACE_INSN (cpu, "RTI;");
1787       /* Do not do IFETCH_CHECK here -- LSB has special meaning.  */
1788       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1789 	illegal_instruction_combination (cpu);
1790       cec_return (cpu, -1);
1791       CYCLE_DELAY = 5;
1792     }
1793   else if (prgfunc == 1 && poprnd == 2)
1794     {
1795       bu32 newpc = RETXREG;
1796       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1797       TRACE_INSN (cpu, "RTX;");
1798       /* XXX: Not sure if this is what the hardware does.  */
1799       IFETCH_CHECK (newpc);
1800       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1801 	illegal_instruction_combination (cpu);
1802       cec_return (cpu, IVG_EVX);
1803       CYCLE_DELAY = 5;
1804     }
1805   else if (prgfunc == 1 && poprnd == 3)
1806     {
1807       bu32 newpc = RETNREG;
1808       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1809       TRACE_INSN (cpu, "RTN;");
1810       /* XXX: Not sure if this is what the hardware does.  */
1811       IFETCH_CHECK (newpc);
1812       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1813 	illegal_instruction_combination (cpu);
1814       cec_return (cpu, IVG_NMI);
1815       CYCLE_DELAY = 5;
1816     }
1817   else if (prgfunc == 1 && poprnd == 4)
1818     {
1819       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1820       TRACE_INSN (cpu, "RTE;");
1821       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1822 	illegal_instruction_combination (cpu);
1823       cec_return (cpu, IVG_EMU);
1824       CYCLE_DELAY = 5;
1825     }
1826   else if (prgfunc == 2 && poprnd == 0)
1827     {
1828       SIM_DESC sd = CPU_STATE (cpu);
1829       sim_events *events = STATE_EVENTS (sd);
1830 
1831       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync);
1832       /* XXX: in supervisor mode, utilizes wake up sources
1833          in user mode, it's a NOP ...  */
1834       TRACE_INSN (cpu, "IDLE;");
1835 
1836       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1837 	illegal_instruction_combination (cpu);
1838 
1839       /* Timewarp !  */
1840       if (events->queue)
1841 	CYCLE_DELAY = events->time_from_event;
1842       else
1843 	abort (); /* XXX: Should this ever happen ?  */
1844     }
1845   else if (prgfunc == 2 && poprnd == 3)
1846     {
1847       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync);
1848       /* Just NOP it.  */
1849       TRACE_INSN (cpu, "CSYNC;");
1850       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1851 	illegal_instruction_combination (cpu);
1852       CYCLE_DELAY = 10;
1853     }
1854   else if (prgfunc == 2 && poprnd == 4)
1855     {
1856       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync);
1857       /* Just NOP it.  */
1858       TRACE_INSN (cpu, "SSYNC;");
1859       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1860 	illegal_instruction_combination (cpu);
1861 
1862       /* Really 10+, but no model info for this.  */
1863       CYCLE_DELAY = 10;
1864     }
1865   else if (prgfunc == 2 && poprnd == 5)
1866     {
1867       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1868       TRACE_INSN (cpu, "EMUEXCPT;");
1869       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1870 	illegal_instruction_combination (cpu);
1871       cec_exception (cpu, VEC_SIM_TRAP);
1872     }
1873   else if (prgfunc == 3 && poprnd < 8)
1874     {
1875       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1876       TRACE_INSN (cpu, "CLI R%i;", poprnd);
1877       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1878 	illegal_instruction_combination (cpu);
1879       SET_DREG (poprnd, cec_cli (cpu));
1880     }
1881   else if (prgfunc == 4 && poprnd < 8)
1882     {
1883       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1884       TRACE_INSN (cpu, "STI R%i;", poprnd);
1885       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1886 	illegal_instruction_combination (cpu);
1887       cec_sti (cpu, DREG (poprnd));
1888       CYCLE_DELAY = 3;
1889     }
1890   else if (prgfunc == 5 && poprnd < 8)
1891     {
1892       bu32 newpc = PREG (poprnd);
1893       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1894       TRACE_INSN (cpu, "JUMP (%s);", get_preg_name (poprnd));
1895       IFETCH_CHECK (newpc);
1896       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1897 	illegal_instruction_combination (cpu);
1898       BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (Preg)");
1899       SET_PCREG (newpc);
1900       BFIN_CPU_STATE.did_jump = true;
1901       PROFILE_BRANCH_TAKEN (cpu);
1902       CYCLE_DELAY = 5;
1903     }
1904   else if (prgfunc == 6 && poprnd < 8)
1905     {
1906       bu32 newpc = PREG (poprnd);
1907       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1908       TRACE_INSN (cpu, "CALL (%s);", get_preg_name (poprnd));
1909       IFETCH_CHECK (newpc);
1910       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1911 	illegal_instruction_combination (cpu);
1912       BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (Preg)");
1913       /* If we're at the end of a hardware loop, RETS is going to be
1914          the top of the loop rather than the next instruction.  */
1915       SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2));
1916       SET_PCREG (newpc);
1917       BFIN_CPU_STATE.did_jump = true;
1918       PROFILE_BRANCH_TAKEN (cpu);
1919       CYCLE_DELAY = 5;
1920     }
1921   else if (prgfunc == 7 && poprnd < 8)
1922     {
1923       bu32 newpc = pc + PREG (poprnd);
1924       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1925       TRACE_INSN (cpu, "CALL (PC + %s);", get_preg_name (poprnd));
1926       IFETCH_CHECK (newpc);
1927       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1928 	illegal_instruction_combination (cpu);
1929       BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (PC + Preg)");
1930       SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2));
1931       SET_PCREG (newpc);
1932       BFIN_CPU_STATE.did_jump = true;
1933       PROFILE_BRANCH_TAKEN (cpu);
1934       CYCLE_DELAY = 5;
1935     }
1936   else if (prgfunc == 8 && poprnd < 8)
1937     {
1938       bu32 newpc = pc + PREG (poprnd);
1939       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1940       TRACE_INSN (cpu, "JUMP (PC + %s);", get_preg_name (poprnd));
1941       IFETCH_CHECK (newpc);
1942       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1943 	illegal_instruction_combination (cpu);
1944       BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (PC + Preg)");
1945       SET_PCREG (newpc);
1946       BFIN_CPU_STATE.did_jump = true;
1947       PROFILE_BRANCH_TAKEN (cpu);
1948       CYCLE_DELAY = 5;
1949     }
1950   else if (prgfunc == 9)
1951     {
1952       int raise = uimm4 (poprnd);
1953       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1954       TRACE_INSN (cpu, "RAISE %s;", uimm4_str (raise));
1955       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1956 	illegal_instruction_combination (cpu);
1957       cec_require_supervisor (cpu);
1958       if (raise == IVG_IVHW)
1959 	cec_hwerr (cpu, HWERR_RAISE_5);
1960       else
1961 	cec_latch (cpu, raise);
1962       CYCLE_DELAY = 3; /* XXX: Only if IVG is unmasked.  */
1963     }
1964   else if (prgfunc == 10)
1965     {
1966       int excpt = uimm4 (poprnd);
1967       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1968       TRACE_INSN (cpu, "EXCPT %s;", uimm4_str (excpt));
1969       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1970 	illegal_instruction_combination (cpu);
1971       cec_exception (cpu, excpt);
1972       CYCLE_DELAY = 3;
1973     }
1974   else if (prgfunc == 11 && poprnd < 6)
1975     {
1976       bu32 addr = PREG (poprnd);
1977       bu8 byte;
1978       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_atomic);
1979       TRACE_INSN (cpu, "TESTSET (%s);", get_preg_name (poprnd));
1980       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
1981 	illegal_instruction_combination (cpu);
1982       byte = GET_WORD (addr);
1983       SET_CCREG (byte == 0);
1984       PUT_BYTE (addr, byte | 0x80);
1985       /* Also includes memory stalls, but we don't model that.  */
1986       CYCLE_DELAY = 2;
1987     }
1988   else
1989     illegal_instruction_or_combination (cpu);
1990 }
1991 
1992 static void
1993 decode_CaCTRL_0 (SIM_CPU *cpu, bu16 iw0)
1994 {
1995   /* CaCTRL
1996      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
1997      | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |.a.|.op....|.reg.......|
1998      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
1999   int a   = ((iw0 >> CaCTRL_a_bits) & CaCTRL_a_mask);
2000   int op  = ((iw0 >> CaCTRL_op_bits) & CaCTRL_op_mask);
2001   int reg = ((iw0 >> CaCTRL_reg_bits) & CaCTRL_reg_mask);
2002   bu32 preg = PREG (reg);
2003   const char * const sinsn[] = { "PREFETCH", "FLUSHINV", "FLUSH", "IFLUSH", };
2004 
2005   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CaCTRL);
2006   TRACE_EXTRACT (cpu, "%s: a:%i op:%i reg:%i", __func__, a, op, reg);
2007   TRACE_INSN (cpu, "%s [%s%s];", sinsn[op], get_preg_name (reg), a ? "++" : "");
2008 
2009   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2010     /* None of these can be part of a parallel instruction.  */
2011     illegal_instruction_combination (cpu);
2012 
2013   /* No cache simulation, so these are (mostly) all NOPs.
2014      XXX: The hardware takes care of masking to cache lines, but need
2015      to check behavior of the post increment.  Should we be aligning
2016      the value to the cache line before adding the cache line size, or
2017      do we just add the cache line size ?  */
2018   if (op == 0)
2019     {	/* PREFETCH  */
2020       mmu_check_cache_addr (cpu, preg, false, false);
2021     }
2022   else if (op == 1)
2023     {	/* FLUSHINV  */
2024       mmu_check_cache_addr (cpu, preg, true, false);
2025     }
2026   else if (op == 2)
2027     {	/* FLUSH  */
2028       mmu_check_cache_addr (cpu, preg, true, false);
2029     }
2030   else if (op == 3)
2031     {	/* IFLUSH  */
2032       mmu_check_cache_addr (cpu, preg, false, true);
2033     }
2034 
2035   if (a)
2036     SET_PREG (reg, preg + BFIN_L1_CACHE_BYTES);
2037 }
2038 
2039 static void
2040 decode_PushPopReg_0 (SIM_CPU *cpu, bu16 iw0)
2041 {
2042   /* PushPopReg
2043      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2044      | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.W.|.grp.......|.reg.......|
2045      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2046   int W   = ((iw0 >> PushPopReg_W_bits) & PushPopReg_W_mask);
2047   int grp = ((iw0 >> PushPopReg_grp_bits) & PushPopReg_grp_mask);
2048   int reg = ((iw0 >> PushPopReg_reg_bits) & PushPopReg_reg_mask);
2049   const char *reg_name = get_allreg_name (grp, reg);
2050   bu32 value;
2051   bu32 sp = SPREG;
2052 
2053   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopReg);
2054   TRACE_EXTRACT (cpu, "%s: W:%i grp:%i reg:%i", __func__, W, grp, reg);
2055   TRACE_DECODE (cpu, "%s: reg:%s", __func__, reg_name);
2056 
2057   /* Can't push/pop reserved registers  */
2058   if (reg_is_reserved (grp, reg))
2059     illegal_instruction_or_combination (cpu);
2060 
2061   if (W == 0)
2062     {
2063       /* Dreg and Preg are not supported by this instruction.  */
2064       if (grp == 0 || grp == 1)
2065 	illegal_instruction_or_combination (cpu);
2066       TRACE_INSN (cpu, "%s = [SP++];", reg_name);
2067       /* Can't pop USP while in userspace.  */
2068       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE
2069 	  || (grp == 7 && reg == 0 && cec_is_user_mode(cpu)))
2070 	illegal_instruction_combination (cpu);
2071       /* XXX: The valid register check is in reg_write(), so we might
2072               incorrectly do a GET_LONG() here ...  */
2073       value = GET_LONG (sp);
2074       reg_write (cpu, grp, reg, value);
2075       if (grp == 7 && reg == 3)
2076 	cec_pop_reti (cpu);
2077 
2078       sp += 4;
2079     }
2080   else
2081     {
2082       TRACE_INSN (cpu, "[--SP] = %s;", reg_name);
2083       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2084 	illegal_instruction_combination (cpu);
2085 
2086       sp -= 4;
2087       value = reg_read (cpu, grp, reg);
2088       if (grp == 7 && reg == 3)
2089 	cec_push_reti (cpu);
2090 
2091       PUT_LONG (sp, value);
2092     }
2093 
2094   /* Note: SP update must be delayed until after all reads/writes; see
2095            comments in decode_PushPopMultiple_0() for more info.  */
2096   SET_SPREG (sp);
2097 }
2098 
2099 static void
2100 decode_PushPopMultiple_0 (SIM_CPU *cpu, bu16 iw0)
2101 {
2102   /* PushPopMultiple
2103      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2104      | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.d.|.p.|.W.|.dr........|.pr........|
2105      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2106   int p  = ((iw0 >> PushPopMultiple_p_bits) & PushPopMultiple_p_mask);
2107   int d  = ((iw0 >> PushPopMultiple_d_bits) & PushPopMultiple_d_mask);
2108   int W  = ((iw0 >> PushPopMultiple_W_bits) & PushPopMultiple_W_mask);
2109   int dr = ((iw0 >> PushPopMultiple_dr_bits) & PushPopMultiple_dr_mask);
2110   int pr = ((iw0 >> PushPopMultiple_pr_bits) & PushPopMultiple_pr_mask);
2111   int i;
2112   bu32 sp = SPREG;
2113 
2114   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopMultiple);
2115   TRACE_EXTRACT (cpu, "%s: d:%i p:%i W:%i dr:%i pr:%i",
2116 		 __func__, d, p, W, dr, pr);
2117 
2118   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2119     illegal_instruction_combination (cpu);
2120 
2121   if ((d == 0 && p == 0) || (p && imm5 (pr) > 5)
2122       || (d && !p && pr) || (p && !d && dr))
2123     illegal_instruction (cpu);
2124 
2125   if (W == 1)
2126     {
2127       if (d && p)
2128 	TRACE_INSN (cpu, "[--SP] = (R7:%i, P5:%i);", dr, pr);
2129       else if (d)
2130 	TRACE_INSN (cpu, "[--SP] = (R7:%i);", dr);
2131       else
2132 	TRACE_INSN (cpu, "[--SP] = (P5:%i);", pr);
2133 
2134       if (d)
2135 	for (i = dr; i < 8; i++)
2136 	  {
2137 	    sp -= 4;
2138 	    PUT_LONG (sp, DREG (i));
2139 	  }
2140       if (p)
2141 	for (i = pr; i < 6; i++)
2142 	  {
2143 	    sp -= 4;
2144 	    PUT_LONG (sp, PREG (i));
2145 	  }
2146 
2147       CYCLE_DELAY = 14;
2148     }
2149   else
2150     {
2151       if (d && p)
2152 	TRACE_INSN (cpu, "(R7:%i, P5:%i) = [SP++];", dr, pr);
2153       else if (d)
2154 	TRACE_INSN (cpu, "(R7:%i) = [SP++];", dr);
2155       else
2156 	TRACE_INSN (cpu, "(P5:%i) = [SP++];", pr);
2157 
2158       if (p)
2159 	for (i = 5; i >= pr; i--)
2160 	  {
2161 	    SET_PREG (i, GET_LONG (sp));
2162 	    sp += 4;
2163 	  }
2164       if (d)
2165 	for (i = 7; i >= dr; i--)
2166 	  {
2167 	    SET_DREG (i, GET_LONG (sp));
2168 	    sp += 4;
2169 	  }
2170 
2171       CYCLE_DELAY = 11;
2172     }
2173 
2174   /* Note: SP update must be delayed until after all reads/writes so that
2175            if an exception does occur, the insn may be re-executed as the
2176            SP has not yet changed.  */
2177   SET_SPREG (sp);
2178 }
2179 
2180 static void
2181 decode_ccMV_0 (SIM_CPU *cpu, bu16 iw0)
2182 {
2183   /* ccMV
2184      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2185      | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.T.|.d.|.s.|.dst.......|.src.......|
2186      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2187   int s  = ((iw0 >> CCmv_s_bits) & CCmv_s_mask);
2188   int d  = ((iw0 >> CCmv_d_bits) & CCmv_d_mask);
2189   int T  = ((iw0 >> CCmv_T_bits) & CCmv_T_mask);
2190   int src = ((iw0 >> CCmv_src_bits) & CCmv_src_mask);
2191   int dst = ((iw0 >> CCmv_dst_bits) & CCmv_dst_mask);
2192   int cond = T ? CCREG : ! CCREG;
2193 
2194   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ccMV);
2195   TRACE_EXTRACT (cpu, "%s: T:%i d:%i s:%i dst:%i src:%i",
2196 		 __func__, T, d, s, dst, src);
2197 
2198   TRACE_INSN (cpu, "IF %sCC %s = %s;", T ? "" : "! ",
2199 	      get_allreg_name (d, dst),
2200 	      get_allreg_name (s, src));
2201   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2202     illegal_instruction_combination (cpu);
2203 
2204   if (cond)
2205     reg_write (cpu, d, dst, reg_read (cpu, s, src));
2206 }
2207 
2208 static void
2209 decode_CCflag_0 (SIM_CPU *cpu, bu16 iw0)
2210 {
2211   /* CCflag
2212      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2213      | 0 | 0 | 0 | 0 | 1 |.I.|.opc.......|.G.|.y.........|.x.........|
2214      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2215   int x = ((iw0 >> CCflag_x_bits) & CCflag_x_mask);
2216   int y = ((iw0 >> CCflag_y_bits) & CCflag_y_mask);
2217   int I = ((iw0 >> CCflag_I_bits) & CCflag_I_mask);
2218   int G = ((iw0 >> CCflag_G_bits) & CCflag_G_mask);
2219   int opc = ((iw0 >> CCflag_opc_bits) & CCflag_opc_mask);
2220 
2221   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CCflag);
2222   TRACE_EXTRACT (cpu, "%s: I:%i opc:%i G:%i y:%i x:%i",
2223 		 __func__, I, opc, G, y, x);
2224 
2225   if (opc > 4)
2226     {
2227       bs64 acc0 = get_extended_acc (cpu, 0);
2228       bs64 acc1 = get_extended_acc (cpu, 1);
2229       bs64 diff = acc0 - acc1;
2230 
2231       if (x != 0 || y != 0)
2232 	illegal_instruction_or_combination (cpu);
2233 
2234       if (opc == 5 && I == 0 && G == 0)
2235 	{
2236 	  TRACE_INSN (cpu, "CC = A0 == A1;");
2237 	  if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2238 	    illegal_instruction_combination (cpu);
2239 	  SET_CCREG (acc0 == acc1);
2240 	}
2241       else if (opc == 6 && I == 0 && G == 0)
2242 	{
2243 	  TRACE_INSN (cpu, "CC = A0 < A1");
2244 	  if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2245 	    illegal_instruction_combination (cpu);
2246 	  SET_CCREG (acc0 < acc1);
2247 	}
2248       else if (opc == 7 && I == 0 && G == 0)
2249 	{
2250 	  TRACE_INSN (cpu, "CC = A0 <= A1");
2251 	  if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2252 	    illegal_instruction_combination (cpu);
2253 	  SET_CCREG (acc0 <= acc1);
2254 	}
2255       else
2256 	illegal_instruction_or_combination (cpu);
2257 
2258       SET_ASTATREG (az, diff == 0);
2259       SET_ASTATREG (an, diff < 0);
2260       SET_ASTATREG (ac0, (bu40)acc1 <= (bu40)acc0);
2261     }
2262   else
2263     {
2264       int issigned = opc < 3;
2265       const char *sign = issigned ? "" : " (IU)";
2266       bu32 srcop = G ? PREG (x) : DREG (x);
2267       char s = G ? 'P' : 'R';
2268       bu32 dstop = I ? (issigned ? imm3 (y) : uimm3 (y)) : G ? PREG (y) : DREG (y);
2269       const char *op;
2270       char d = G ? 'P' : 'R';
2271       int flgs = srcop >> 31;
2272       int flgo = dstop >> 31;
2273 
2274       bu32 result = srcop - dstop;
2275       int cc;
2276       int flgn = result >> 31;
2277       int overflow = (flgs ^ flgo) & (flgn ^ flgs);
2278       int az = result == 0;
2279       int ac0 = dstop <= srcop;
2280       int an;
2281       if (issigned)
2282 	an = (flgn && !overflow) || (!flgn && overflow);
2283       else
2284 	an = dstop > srcop;
2285 
2286       switch (opc)
2287 	{
2288 	default: /* Shutup useless gcc warnings.  */
2289 	case 0: /* signed  */
2290 	  op = "==";
2291 	  cc = az;
2292 	  break;
2293 	case 1:	/* signed  */
2294 	  op = "<";
2295 	  cc = an;
2296 	  break;
2297 	case 2:	/* signed  */
2298 	  op = "<=";
2299 	  cc = an || az;
2300 	  break;
2301 	case 3:	/* unsigned  */
2302 	  op = "<";
2303 	  cc = !ac0;
2304 	  break;
2305 	case 4:	/* unsigned  */
2306 	  op = "<=";
2307 	  cc = !ac0 || az;
2308 	  break;
2309 	}
2310 
2311       if (I)
2312 	TRACE_INSN (cpu, "CC = %c%i %s %s%s;", s, x, op,
2313 		    issigned ? imm3_str (y) : uimm3_str (y), sign);
2314       else
2315 	{
2316 	  TRACE_DECODE (cpu, "%s %c%i:%x %c%i:%x", __func__,
2317 			s, x, srcop,  d, y, dstop);
2318 	  TRACE_INSN (cpu, "CC = %c%i %s %c%i%s;", s, x, op, d, y, sign);
2319 	}
2320 
2321       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2322 	illegal_instruction_combination (cpu);
2323 
2324       SET_CCREG (cc);
2325       /* Pointer compares only touch CC.  */
2326       if (!G)
2327 	{
2328 	  SET_ASTATREG (az, az);
2329 	  SET_ASTATREG (an, an);
2330 	  SET_ASTATREG (ac0, ac0);
2331 	}
2332     }
2333 }
2334 
2335 static void
2336 decode_CC2dreg_0 (SIM_CPU *cpu, bu16 iw0)
2337 {
2338   /* CC2dreg
2339      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2340      | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |.op....|.reg.......|
2341      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2342   int op  = ((iw0 >> CC2dreg_op_bits) & CC2dreg_op_mask);
2343   int reg = ((iw0 >> CC2dreg_reg_bits) & CC2dreg_reg_mask);
2344 
2345   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2dreg);
2346   TRACE_EXTRACT (cpu, "%s: op:%i reg:%i", __func__, op, reg);
2347 
2348   if (op == 0)
2349     {
2350       TRACE_INSN (cpu, "R%i = CC;", reg);
2351       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2352 	illegal_instruction_combination (cpu);
2353       SET_DREG (reg, CCREG);
2354     }
2355   else if (op == 1)
2356     {
2357       TRACE_INSN (cpu, "CC = R%i;", reg);
2358       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2359 	illegal_instruction_combination (cpu);
2360       SET_CCREG (DREG (reg) != 0);
2361     }
2362   else if (op == 3 && reg == 0)
2363     {
2364       TRACE_INSN (cpu, "CC = !CC;");
2365       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2366 	illegal_instruction_combination (cpu);
2367       SET_CCREG (!CCREG);
2368     }
2369   else
2370     illegal_instruction_or_combination (cpu);
2371 }
2372 
2373 static void
2374 decode_CC2stat_0 (SIM_CPU *cpu, bu16 iw0)
2375 {
2376   /* CC2stat
2377      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2378      | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.D.|.op....|.cbit..............|
2379      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2380   int D    = ((iw0 >> CC2stat_D_bits) & CC2stat_D_mask);
2381   int op   = ((iw0 >> CC2stat_op_bits) & CC2stat_op_mask);
2382   int cbit = ((iw0 >> CC2stat_cbit_bits) & CC2stat_cbit_mask);
2383   bu32 pval;
2384 
2385   const char * const op_names[] = { "", "|", "&", "^" } ;
2386 
2387   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2stat);
2388   TRACE_EXTRACT (cpu, "%s: D:%i op:%i cbit:%i", __func__, D, op, cbit);
2389 
2390   TRACE_INSN (cpu, "%s %s= %s;", D ? astat_names[cbit] : "CC",
2391 	      op_names[op], D ? "CC" : astat_names[cbit]);
2392 
2393   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2394     illegal_instruction_combination (cpu);
2395 
2396   /* CC = CC; is invalid.  */
2397   if (cbit == 5)
2398     illegal_instruction (cpu);
2399 
2400   pval = !!(ASTAT & (1 << cbit));
2401   if (D == 0)
2402     switch (op)
2403       {
2404       case 0: SET_CCREG (pval); break;
2405       case 1: SET_CCREG (CCREG | pval); break;
2406       case 2: SET_CCREG (CCREG & pval); break;
2407       case 3: SET_CCREG (CCREG ^ pval); break;
2408       }
2409   else
2410     {
2411       switch (op)
2412 	{
2413 	case 0: pval  = CCREG; break;
2414 	case 1: pval |= CCREG; break;
2415 	case 2: pval &= CCREG; break;
2416 	case 3: pval ^= CCREG; break;
2417 	}
2418       TRACE_REGISTER (cpu, "wrote ASTAT[%s] = %i", astat_names[cbit], pval);
2419       SET_ASTAT ((ASTAT & ~(1 << cbit)) | (pval << cbit));
2420     }
2421 }
2422 
2423 static void
2424 decode_BRCC_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc)
2425 {
2426   /* BRCC
2427      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2428      | 0 | 0 | 0 | 1 |.T.|.B.|.offset................................|
2429      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2430   int B = ((iw0 >> BRCC_B_bits) & BRCC_B_mask);
2431   int T = ((iw0 >> BRCC_T_bits) & BRCC_T_mask);
2432   int offset = ((iw0 >> BRCC_offset_bits) & BRCC_offset_mask);
2433   int cond = T ? CCREG : ! CCREG;
2434   int pcrel = pcrel10 (offset);
2435 
2436   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_BRCC);
2437   TRACE_EXTRACT (cpu, "%s: T:%i B:%i offset:%#x", __func__, T, B, offset);
2438   TRACE_DECODE (cpu, "%s: pcrel10:%#x", __func__, pcrel);
2439 
2440   TRACE_INSN (cpu, "IF %sCC JUMP %#x%s;", T ? "" : "! ",
2441 	      pcrel, B ? " (bp)" : "");
2442 
2443   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2444     illegal_instruction_combination (cpu);
2445 
2446   if (cond)
2447     {
2448       bu32 newpc = pc + pcrel;
2449       BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "Conditional JUMP");
2450       SET_PCREG (newpc);
2451       BFIN_CPU_STATE.did_jump = true;
2452       PROFILE_BRANCH_TAKEN (cpu);
2453       CYCLE_DELAY = B ? 5 : 9;
2454     }
2455   else
2456     {
2457       PROFILE_BRANCH_UNTAKEN (cpu);
2458       CYCLE_DELAY = B ? 9 : 1;
2459     }
2460 }
2461 
2462 static void
2463 decode_UJUMP_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc)
2464 {
2465   /* UJUMP
2466      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2467      | 0 | 0 | 1 | 0 |.offset........................................|
2468      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2469   int offset = ((iw0 >> UJump_offset_bits) & UJump_offset_mask);
2470   int pcrel = pcrel12 (offset);
2471   bu32 newpc = pc + pcrel;
2472 
2473   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_UJUMP);
2474   TRACE_EXTRACT (cpu, "%s: offset:%#x", __func__, offset);
2475   TRACE_DECODE (cpu, "%s: pcrel12:%#x", __func__, pcrel);
2476 
2477   TRACE_INSN (cpu, "JUMP.S %#x;", pcrel);
2478 
2479   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2480     illegal_instruction_combination (cpu);
2481 
2482   BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.S");
2483 
2484   SET_PCREG (newpc);
2485   BFIN_CPU_STATE.did_jump = true;
2486   PROFILE_BRANCH_TAKEN (cpu);
2487   CYCLE_DELAY = 5;
2488 }
2489 
2490 static void
2491 decode_REGMV_0 (SIM_CPU *cpu, bu16 iw0)
2492 {
2493   /* REGMV
2494      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2495      | 0 | 0 | 1 | 1 |.gd........|.gs........|.dst.......|.src.......|
2496      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2497   int gs  = ((iw0 >> RegMv_gs_bits) & RegMv_gs_mask);
2498   int gd  = ((iw0 >> RegMv_gd_bits) & RegMv_gd_mask);
2499   int src = ((iw0 >> RegMv_src_bits) & RegMv_src_mask);
2500   int dst = ((iw0 >> RegMv_dst_bits) & RegMv_dst_mask);
2501   const char *srcreg_name = get_allreg_name (gs, src);
2502   const char *dstreg_name = get_allreg_name (gd, dst);
2503 
2504   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_REGMV);
2505   TRACE_EXTRACT (cpu, "%s: gd:%i gs:%i dst:%i src:%i",
2506 		 __func__, gd, gs, dst, src);
2507   TRACE_DECODE (cpu, "%s: dst:%s src:%s", __func__, dstreg_name, srcreg_name);
2508 
2509   TRACE_INSN (cpu, "%s = %s;", dstreg_name, srcreg_name);
2510 
2511   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2512     illegal_instruction_combination (cpu);
2513 
2514   /* Reserved slots cannot be a src/dst.  */
2515   if (reg_is_reserved (gs, src) || reg_is_reserved (gd, dst))
2516     goto invalid_move;
2517 
2518   /* Standard register moves.  */
2519   if ((gs < 2)						/* Dregs/Pregs src  */
2520       || (gd < 2)					/* Dregs/Pregs dst  */
2521       || (gs == 4 && src < 4)				/* Accumulators src  */
2522       || (gd == 4 && dst < 4 && (gs < 4))		/* Accumulators dst  */
2523       || (gs == 7 && src == 7 && !(gd == 4 && dst < 4))	/* EMUDAT src  */
2524       || (gd == 7 && dst == 7)) 			/* EMUDAT dst  */
2525     goto valid_move;
2526 
2527   /* dareg = dareg (IMBL)  */
2528   if (gs < 4 && gd < 4)
2529     goto valid_move;
2530 
2531   /* USP can be src to sysregs, but not dagregs.  */
2532   if ((gs == 7 && src == 0) && (gd >= 4))
2533     goto valid_move;
2534 
2535   /* USP can move between genregs (only check Accumulators).  */
2536   if (((gs == 7 && src == 0) && (gd == 4 && dst < 4))
2537       || ((gd == 7 && dst == 0) && (gs == 4 && src < 4)))
2538     goto valid_move;
2539 
2540   /* Still here ?  Invalid reg pair.  */
2541  invalid_move:
2542   illegal_instruction (cpu);
2543 
2544  valid_move:
2545   reg_write (cpu, gd, dst, reg_read (cpu, gs, src));
2546 }
2547 
2548 static void
2549 decode_ALU2op_0 (SIM_CPU *cpu, bu16 iw0)
2550 {
2551   /* ALU2op
2552      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2553      | 0 | 1 | 0 | 0 | 0 | 0 |.opc...........|.src.......|.dst.......|
2554      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2555   int src = ((iw0 >> ALU2op_src_bits) & ALU2op_src_mask);
2556   int opc = ((iw0 >> ALU2op_opc_bits) & ALU2op_opc_mask);
2557   int dst = ((iw0 >> ALU2op_dst_bits) & ALU2op_dst_mask);
2558 
2559   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ALU2op);
2560   TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst);
2561 
2562   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2563     illegal_instruction_combination (cpu);
2564 
2565   if (opc == 0)
2566     {
2567       TRACE_INSN (cpu, "R%i >>>= R%i;", dst, src);
2568       SET_DREG (dst, ashiftrt (cpu, DREG (dst), DREG (src), 32));
2569     }
2570   else if (opc == 1)
2571     {
2572       bu32 val;
2573       TRACE_INSN (cpu, "R%i >>= R%i;", dst, src);
2574       if (DREG (src) <= 0x1F)
2575 	val = lshiftrt (cpu, DREG (dst), DREG (src), 32);
2576       else
2577 	val = 0;
2578       SET_DREG (dst, val);
2579     }
2580   else if (opc == 2)
2581     {
2582       TRACE_INSN (cpu, "R%i <<= R%i;", dst, src);
2583       SET_DREG (dst, lshift (cpu, DREG (dst), DREG (src), 32, 0, 0));
2584     }
2585   else if (opc == 3)
2586     {
2587       TRACE_INSN (cpu, "R%i *= R%i;", dst, src);
2588       SET_DREG (dst, DREG (dst) * DREG (src));
2589       CYCLE_DELAY = 3;
2590     }
2591   else if (opc == 4)
2592     {
2593       TRACE_INSN (cpu, "R%i = (R%i + R%i) << 1;", dst, dst, src);
2594       SET_DREG (dst, add_and_shift (cpu, DREG (dst), DREG (src), 1));
2595     }
2596   else if (opc == 5)
2597     {
2598       TRACE_INSN (cpu, "R%i = (R%i + R%i) << 2;", dst, dst, src);
2599       SET_DREG (dst, add_and_shift (cpu, DREG (dst), DREG (src), 2));
2600     }
2601   else if (opc == 8)
2602     {
2603       TRACE_INSN (cpu, "DIVQ ( R%i, R%i );", dst, src);
2604       SET_DREG (dst, divq (cpu, DREG (dst), (bu16)DREG (src)));
2605     }
2606   else if (opc == 9)
2607     {
2608       TRACE_INSN (cpu, "DIVS ( R%i, R%i );", dst, src);
2609       SET_DREG (dst, divs (cpu, DREG (dst), (bu16)DREG (src)));
2610     }
2611   else if (opc == 10)
2612     {
2613       TRACE_INSN (cpu, "R%i = R%i.L (X);", dst, src);
2614       SET_DREG (dst, (bs32) (bs16) DREG (src));
2615       setflags_logical (cpu, DREG (dst));
2616     }
2617   else if (opc == 11)
2618     {
2619       TRACE_INSN (cpu, "R%i = R%i.L (Z);", dst, src);
2620       SET_DREG (dst, (bu32) (bu16) DREG (src));
2621       setflags_logical (cpu, DREG (dst));
2622     }
2623   else if (opc == 12)
2624     {
2625       TRACE_INSN (cpu, "R%i = R%i.B (X);", dst, src);
2626       SET_DREG (dst, (bs32) (bs8) DREG (src));
2627       setflags_logical (cpu, DREG (dst));
2628     }
2629   else if (opc == 13)
2630     {
2631       TRACE_INSN (cpu, "R%i = R%i.B (Z);", dst, src);
2632       SET_DREG (dst, (bu32) (bu8) DREG (src));
2633       setflags_logical (cpu, DREG (dst));
2634     }
2635   else if (opc == 14)
2636     {
2637       bu32 val = DREG (src);
2638       TRACE_INSN (cpu, "R%i = - R%i;", dst, src);
2639       SET_DREG (dst, -val);
2640       setflags_nz (cpu, DREG (dst));
2641       SET_ASTATREG (v, val == 0x80000000);
2642       if (ASTATREG (v))
2643 	SET_ASTATREG (vs, 1);
2644       SET_ASTATREG (ac0, val == 0x0);
2645       /* XXX: Documentation isn't entirely clear about av0 and av1.  */
2646     }
2647   else if (opc == 15)
2648     {
2649       TRACE_INSN (cpu, "R%i = ~ R%i;", dst, src);
2650       SET_DREG (dst, ~DREG (src));
2651       setflags_logical (cpu, DREG (dst));
2652     }
2653   else
2654     illegal_instruction (cpu);
2655 }
2656 
2657 static void
2658 decode_PTR2op_0 (SIM_CPU *cpu, bu16 iw0)
2659 {
2660   /* PTR2op
2661      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2662      | 0 | 1 | 0 | 0 | 0 | 1 | 0 |.opc.......|.src.......|.dst.......|
2663      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2664   int src = ((iw0 >> PTR2op_src_bits) & PTR2op_dst_mask);
2665   int opc = ((iw0 >> PTR2op_opc_bits) & PTR2op_opc_mask);
2666   int dst = ((iw0 >> PTR2op_dst_bits) & PTR2op_dst_mask);
2667   const char *src_name = get_preg_name (src);
2668   const char *dst_name = get_preg_name (dst);
2669 
2670   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PTR2op);
2671   TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst);
2672 
2673   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2674     illegal_instruction_combination (cpu);
2675 
2676   if (opc == 0)
2677     {
2678       TRACE_INSN (cpu, "%s -= %s", dst_name, src_name);
2679       SET_PREG (dst, PREG (dst) - PREG (src));
2680     }
2681   else if (opc == 1)
2682     {
2683       TRACE_INSN (cpu, "%s = %s << 2", dst_name, src_name);
2684       SET_PREG (dst, PREG (src) << 2);
2685     }
2686   else if (opc == 3)
2687     {
2688       TRACE_INSN (cpu, "%s = %s >> 2", dst_name, src_name);
2689       SET_PREG (dst, PREG (src) >> 2);
2690     }
2691   else if (opc == 4)
2692     {
2693       TRACE_INSN (cpu, "%s = %s >> 1", dst_name, src_name);
2694       SET_PREG (dst, PREG (src) >> 1);
2695     }
2696   else if (opc == 5)
2697     {
2698       TRACE_INSN (cpu, "%s += %s (BREV)", dst_name, src_name);
2699       SET_PREG (dst, add_brev (PREG (dst), PREG (src)));
2700     }
2701   else if (opc == 6)
2702     {
2703       TRACE_INSN (cpu, "%s = (%s + %s) << 1", dst_name, dst_name, src_name);
2704       SET_PREG (dst, (PREG (dst) + PREG (src)) << 1);
2705     }
2706   else if (opc == 7)
2707     {
2708       TRACE_INSN (cpu, "%s = (%s + %s) << 2", dst_name, dst_name, src_name);
2709       SET_PREG (dst, (PREG (dst) + PREG (src)) << 2);
2710     }
2711   else
2712     illegal_instruction (cpu);
2713 }
2714 
2715 static void
2716 decode_LOGI2op_0 (SIM_CPU *cpu, bu16 iw0)
2717 {
2718   /* LOGI2op
2719      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2720      | 0 | 1 | 0 | 0 | 1 |.opc.......|.src...............|.dst.......|
2721      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2722   int src = ((iw0 >> LOGI2op_src_bits) & LOGI2op_src_mask);
2723   int opc = ((iw0 >> LOGI2op_opc_bits) & LOGI2op_opc_mask);
2724   int dst = ((iw0 >> LOGI2op_dst_bits) & LOGI2op_dst_mask);
2725   int uimm = uimm5 (src);
2726   const char *uimm_str = uimm5_str (uimm);
2727 
2728   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LOGI2op);
2729   TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst);
2730   TRACE_DECODE (cpu, "%s: uimm5:%#x", __func__, uimm);
2731 
2732   if (opc == 0)
2733     {
2734       TRACE_INSN (cpu, "CC = ! BITTST (R%i, %s);", dst, uimm_str);
2735       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2736 	illegal_instruction_combination (cpu);
2737       SET_CCREG ((~DREG (dst) >> uimm) & 1);
2738     }
2739   else if (opc == 1)
2740     {
2741       TRACE_INSN (cpu, "CC = BITTST (R%i, %s);", dst, uimm_str);
2742       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2743 	illegal_instruction_combination (cpu);
2744       SET_CCREG ((DREG (dst) >> uimm) & 1);
2745     }
2746   else if (opc == 2)
2747     {
2748       TRACE_INSN (cpu, "BITSET (R%i, %s);", dst, uimm_str);
2749       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2750 	illegal_instruction_combination (cpu);
2751       SET_DREG (dst, DREG (dst) | (1 << uimm));
2752       setflags_logical (cpu, DREG (dst));
2753     }
2754   else if (opc == 3)
2755     {
2756       TRACE_INSN (cpu, "BITTGL (R%i, %s);", dst, uimm_str);
2757       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2758 	illegal_instruction_combination (cpu);
2759       SET_DREG (dst, DREG (dst) ^ (1 << uimm));
2760       setflags_logical (cpu, DREG (dst));
2761     }
2762   else if (opc == 4)
2763     {
2764       TRACE_INSN (cpu, "BITCLR (R%i, %s);", dst, uimm_str);
2765       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2766 	illegal_instruction_combination (cpu);
2767       SET_DREG (dst, DREG (dst) & ~(1 << uimm));
2768       setflags_logical (cpu, DREG (dst));
2769     }
2770   else if (opc == 5)
2771     {
2772       TRACE_INSN (cpu, "R%i >>>= %s;", dst, uimm_str);
2773       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2774 	illegal_instruction_combination (cpu);
2775       SET_DREG (dst, ashiftrt (cpu, DREG (dst), uimm, 32));
2776     }
2777   else if (opc == 6)
2778     {
2779       TRACE_INSN (cpu, "R%i >>= %s;", dst, uimm_str);
2780       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2781 	illegal_instruction_combination (cpu);
2782       SET_DREG (dst, lshiftrt (cpu, DREG (dst), uimm, 32));
2783     }
2784   else if (opc == 7)
2785     {
2786       TRACE_INSN (cpu, "R%i <<= %s;", dst, uimm_str);
2787       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2788 	illegal_instruction_combination (cpu);
2789       SET_DREG (dst, lshift (cpu, DREG (dst), uimm, 32, 0, 0));
2790     }
2791 }
2792 
2793 static void
2794 decode_COMP3op_0 (SIM_CPU *cpu, bu16 iw0)
2795 {
2796   /* COMP3op
2797      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2798      | 0 | 1 | 0 | 1 |.opc.......|.dst.......|.src1......|.src0......|
2799      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2800   int opc  = ((iw0 >> COMP3op_opc_bits) & COMP3op_opc_mask);
2801   int dst  = ((iw0 >> COMP3op_dst_bits) & COMP3op_dst_mask);
2802   int src0 = ((iw0 >> COMP3op_src0_bits) & COMP3op_src0_mask);
2803   int src1 = ((iw0 >> COMP3op_src1_bits) & COMP3op_src1_mask);
2804 
2805   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMP3op);
2806   TRACE_EXTRACT (cpu, "%s: opc:%i dst:%i src1:%i src0:%i",
2807 		 __func__, opc, dst, src1, src0);
2808 
2809   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2810     illegal_instruction_combination (cpu);
2811 
2812   if (opc == 0)
2813     {
2814       TRACE_INSN (cpu, "R%i = R%i + R%i;", dst, src0, src1);
2815       SET_DREG (dst, add32 (cpu, DREG (src0), DREG (src1), 1, 0));
2816     }
2817   else if (opc == 1)
2818     {
2819       TRACE_INSN (cpu, "R%i = R%i - R%i;", dst, src0, src1);
2820       SET_DREG (dst, sub32 (cpu, DREG (src0), DREG (src1), 1, 0, 0));
2821     }
2822   else if (opc == 2)
2823     {
2824       TRACE_INSN (cpu, "R%i = R%i & R%i;", dst, src0, src1);
2825       SET_DREG (dst, DREG (src0) & DREG (src1));
2826       setflags_logical (cpu, DREG (dst));
2827     }
2828   else if (opc == 3)
2829     {
2830       TRACE_INSN (cpu, "R%i = R%i | R%i;", dst, src0, src1);
2831       SET_DREG (dst, DREG (src0) | DREG (src1));
2832       setflags_logical (cpu, DREG (dst));
2833     }
2834   else if (opc == 4)
2835     {
2836       TRACE_INSN (cpu, "R%i = R%i ^ R%i;", dst, src0, src1);
2837       SET_DREG (dst, DREG (src0) ^ DREG (src1));
2838       setflags_logical (cpu, DREG (dst));
2839     }
2840   else
2841     {
2842       int shift = opc - 5;
2843       const char *dst_name = get_preg_name (dst);
2844       const char *src0_name = get_preg_name (src0);
2845       const char *src1_name = get_preg_name (src1);
2846 
2847       /* If src0 == src1 this is disassembled as a shift by 1, but this
2848          distinction doesn't matter for our purposes.  */
2849       if (shift)
2850 	TRACE_INSN (cpu, "%s = (%s + %s) << %#x;",
2851 		    dst_name, src0_name, src1_name, shift);
2852       else
2853 	TRACE_INSN (cpu, "%s = %s + %s",
2854 		    dst_name, src0_name, src1_name);
2855       SET_PREG (dst, PREG (src0) + (PREG (src1) << shift));
2856     }
2857 }
2858 
2859 static void
2860 decode_COMPI2opD_0 (SIM_CPU *cpu, bu16 iw0)
2861 {
2862   /* COMPI2opD
2863      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2864      | 0 | 1 | 1 | 0 | 0 |.op|..src......................|.dst.......|
2865      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2866   int op  = ((iw0 >> COMPI2opD_op_bits) & COMPI2opD_op_mask);
2867   int dst = ((iw0 >> COMPI2opD_dst_bits) & COMPI2opD_dst_mask);
2868   int src = ((iw0 >> COMPI2opD_src_bits) & COMPI2opD_src_mask);
2869   int imm = imm7 (src);
2870 
2871   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opD);
2872   TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst);
2873   TRACE_DECODE (cpu, "%s: imm7:%#x", __func__, imm);
2874 
2875   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2876     illegal_instruction_combination (cpu);
2877 
2878   if (op == 0)
2879     {
2880       TRACE_INSN (cpu, "R%i = %s (X);", dst, imm7_str (imm));
2881       SET_DREG (dst, imm);
2882     }
2883   else if (op == 1)
2884     {
2885       TRACE_INSN (cpu, "R%i += %s;", dst, imm7_str (imm));
2886       SET_DREG (dst, add32 (cpu, DREG (dst), imm, 1, 0));
2887     }
2888 }
2889 
2890 static void
2891 decode_COMPI2opP_0 (SIM_CPU *cpu, bu16 iw0)
2892 {
2893   /* COMPI2opP
2894      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2895      | 0 | 1 | 1 | 0 | 1 |.op|.src.......................|.dst.......|
2896      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2897   int op  = ((iw0 >> COMPI2opP_op_bits) & COMPI2opP_op_mask);
2898   int src = ((iw0 >> COMPI2opP_src_bits) & COMPI2opP_src_mask);
2899   int dst = ((iw0 >> COMPI2opP_dst_bits) & COMPI2opP_dst_mask);
2900   int imm = imm7 (src);
2901   const char *dst_name = get_preg_name (dst);
2902 
2903   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opP);
2904   TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst);
2905   TRACE_DECODE (cpu, "%s: imm:%#x", __func__, imm);
2906 
2907   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
2908     illegal_instruction_combination (cpu);
2909 
2910   if (op == 0)
2911     {
2912       TRACE_INSN (cpu, "%s = %s;", dst_name, imm7_str (imm));
2913       SET_PREG (dst, imm);
2914     }
2915   else if (op == 1)
2916     {
2917       TRACE_INSN (cpu, "%s += %s;", dst_name, imm7_str (imm));
2918       SET_PREG (dst, PREG (dst) + imm);
2919     }
2920 }
2921 
2922 static void
2923 decode_LDSTpmod_0 (SIM_CPU *cpu, bu16 iw0)
2924 {
2925   /* LDSTpmod
2926      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2927      | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2928      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2929   int W   = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
2930   int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
2931   int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
2932   int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
2933   int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
2934   const char *ptr_name = get_preg_name (ptr);
2935   const char *idx_name = get_preg_name (idx);
2936   bu32 addr, val;
2937 
2938   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTpmod);
2939   TRACE_EXTRACT (cpu, "%s: W:%i aop:%i reg:%i idx:%i ptr:%i",
2940 		 __func__, W, aop, reg, idx, ptr);
2941 
2942   if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2)
2943     illegal_instruction_combination (cpu);
2944 
2945   if (aop == 1 && W == 0 && idx == ptr)
2946     {
2947       TRACE_INSN (cpu, "R%i.L = W[%s];", reg, ptr_name);
2948       addr = PREG (ptr);
2949       val = GET_WORD (addr);
2950       STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | val);
2951     }
2952   else if (aop == 2 && W == 0 && idx == ptr)
2953     {
2954       TRACE_INSN (cpu, "R%i.H = W[%s];", reg, ptr_name);
2955       addr = PREG (ptr);
2956       val = GET_WORD (addr);
2957       STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (val << 16));
2958     }
2959   else if (aop == 1 && W == 1 && idx == ptr)
2960     {
2961       TRACE_INSN (cpu, "W[%s] = R%i.L;", ptr_name, reg);
2962       addr = PREG (ptr);
2963       PUT_WORD (addr, DREG (reg));
2964     }
2965   else if (aop == 2 && W == 1 && idx == ptr)
2966     {
2967       TRACE_INSN (cpu, "W[%s] = R%i.H;", ptr_name, reg);
2968       addr = PREG (ptr);
2969       PUT_WORD (addr, DREG (reg) >> 16);
2970     }
2971   else if (aop == 0 && W == 0)
2972     {
2973       TRACE_INSN (cpu, "R%i = [%s ++ %s];", reg, ptr_name, idx_name);
2974       addr = PREG (ptr);
2975       val = GET_LONG (addr);
2976       STORE (DREG (reg), val);
2977       if (ptr != idx)
2978 	STORE (PREG (ptr), addr + PREG (idx));
2979     }
2980   else if (aop == 1 && W == 0)
2981     {
2982       TRACE_INSN (cpu, "R%i.L = W[%s ++ %s];", reg, ptr_name, idx_name);
2983       addr = PREG (ptr);
2984       val = GET_WORD (addr);
2985       STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | val);
2986       if (ptr != idx)
2987 	STORE (PREG (ptr), addr + PREG (idx));
2988     }
2989   else if (aop == 2 && W == 0)
2990     {
2991       TRACE_INSN (cpu, "R%i.H = W[%s ++ %s];", reg, ptr_name, idx_name);
2992       addr = PREG (ptr);
2993       val = GET_WORD (addr);
2994       STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (val << 16));
2995       if (ptr != idx)
2996 	STORE (PREG (ptr), addr + PREG (idx));
2997     }
2998   else if (aop == 3 && W == 0)
2999     {
3000       TRACE_INSN (cpu, "R%i = W[%s ++ %s] (Z);", reg, ptr_name, idx_name);
3001       addr = PREG (ptr);
3002       val = GET_WORD (addr);
3003       STORE (DREG (reg), val);
3004       if (ptr != idx)
3005 	STORE (PREG (ptr), addr + PREG (idx));
3006     }
3007   else if (aop == 3 && W == 1)
3008     {
3009       TRACE_INSN (cpu, "R%i = W[%s ++ %s] (X);", reg, ptr_name, idx_name);
3010       addr = PREG (ptr);
3011       val = GET_WORD (addr);
3012       STORE (DREG (reg), (bs32) (bs16) val);
3013       if (ptr != idx)
3014 	STORE (PREG (ptr), addr + PREG (idx));
3015     }
3016   else if (aop == 0 && W == 1)
3017     {
3018       TRACE_INSN (cpu, "[%s ++ %s] = R%i;", ptr_name, idx_name, reg);
3019       addr = PREG (ptr);
3020       PUT_LONG (addr, DREG (reg));
3021       if (ptr != idx)
3022 	STORE (PREG (ptr), addr + PREG (idx));
3023     }
3024   else if (aop == 1 && W == 1)
3025     {
3026       TRACE_INSN (cpu, "W[%s ++ %s] = R%i.L;", ptr_name, idx_name, reg);
3027       addr = PREG (ptr);
3028       PUT_WORD (addr, DREG (reg));
3029       if (ptr != idx)
3030 	STORE (PREG (ptr), addr + PREG (idx));
3031     }
3032   else if (aop == 2 && W == 1)
3033     {
3034       TRACE_INSN (cpu, "W[%s ++ %s] = R%i.H;", ptr_name, idx_name, reg);
3035       addr = PREG (ptr);
3036       PUT_WORD (addr, DREG (reg) >> 16);
3037       if (ptr != idx)
3038 	STORE (PREG (ptr), addr + PREG (idx));
3039     }
3040   else
3041     illegal_instruction_or_combination (cpu);
3042 }
3043 
3044 static void
3045 decode_dagMODim_0 (SIM_CPU *cpu, bu16 iw0)
3046 {
3047   /* dagMODim
3048      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3049      | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
3050      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3051   int i  = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
3052   int m  = ((iw0 >> DagMODim_m_bits) & DagMODim_m_mask);
3053   int br = ((iw0 >> DagMODim_br_bits) & DagMODim_br_mask);
3054   int op = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
3055 
3056   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODim);
3057   TRACE_EXTRACT (cpu, "%s: br:%i op:%i m:%i i:%i", __func__, br, op, m, i);
3058 
3059   if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2)
3060     illegal_instruction_combination (cpu);
3061 
3062   if (op == 0 && br == 1)
3063     {
3064       TRACE_INSN (cpu, "I%i += M%i (BREV);", i, m);
3065       SET_IREG (i, add_brev (IREG (i), MREG (m)));
3066     }
3067   else if (op == 0)
3068     {
3069       TRACE_INSN (cpu, "I%i += M%i;", i, m);
3070       dagadd (cpu, i, MREG (m));
3071     }
3072   else if (op == 1 && br == 0)
3073     {
3074       TRACE_INSN (cpu, "I%i -= M%i;", i, m);
3075       dagsub (cpu, i, MREG (m));
3076     }
3077   else
3078     illegal_instruction_or_combination (cpu);
3079 }
3080 
3081 static void
3082 decode_dagMODik_0 (SIM_CPU *cpu, bu16 iw0)
3083 {
3084   /* dagMODik
3085      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3086      | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
3087      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3088   int i  = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
3089   int op = ((iw0 >> DagMODik_op_bits) & DagMODik_op_mask);
3090 
3091   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODik);
3092   TRACE_EXTRACT (cpu, "%s: op:%i i:%i", __func__, op, i);
3093 
3094   if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2)
3095     illegal_instruction_combination (cpu);
3096 
3097   if (op == 0)
3098     {
3099       TRACE_INSN (cpu, "I%i += 2;", i);
3100       dagadd (cpu, i, 2);
3101     }
3102   else if (op == 1)
3103     {
3104       TRACE_INSN (cpu, "I%i -= 2;", i);
3105       dagsub (cpu, i, 2);
3106     }
3107   else if (op == 2)
3108     {
3109       TRACE_INSN (cpu, "I%i += 4;", i);
3110       dagadd (cpu, i, 4);
3111     }
3112   else if (op == 3)
3113     {
3114       TRACE_INSN (cpu, "I%i -= 4;", i);
3115       dagsub (cpu, i, 4);
3116     }
3117   else
3118     illegal_instruction_or_combination (cpu);
3119 }
3120 
3121 static void
3122 decode_dspLDST_0 (SIM_CPU *cpu, bu16 iw0)
3123 {
3124   /* dspLDST
3125      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3126      | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
3127      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3128   int i   = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
3129   int m   = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
3130   int W   = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
3131   int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
3132   int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
3133   bu32 addr;
3134 
3135   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dspLDST);
3136   TRACE_EXTRACT (cpu, "%s: aop:%i m:%i i:%i reg:%i", __func__, aop, m, i, reg);
3137 
3138   if (aop == 0 && W == 0 && m == 0)
3139     {
3140       TRACE_INSN (cpu, "R%i = [I%i++];", reg, i);
3141       addr = IREG (i);
3142       if (DIS_ALGN_EXPT & 0x1)
3143 	addr &= ~3;
3144       dagadd (cpu, i, 4);
3145       STORE (DREG (reg), GET_LONG (addr));
3146     }
3147   else if (aop == 0 && W == 0 && m == 1)
3148     {
3149       TRACE_INSN (cpu, "R%i.L = W[I%i++];", reg, i);
3150       addr = IREG (i);
3151       dagadd (cpu, i, 2);
3152       STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | GET_WORD (addr));
3153     }
3154   else if (aop == 0 && W == 0 && m == 2)
3155     {
3156       TRACE_INSN (cpu, "R%i.H = W[I%i++];", reg, i);
3157       addr = IREG (i);
3158       dagadd (cpu, i, 2);
3159       STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (GET_WORD (addr) << 16));
3160     }
3161   else if (aop == 1 && W == 0 && m == 0)
3162     {
3163       TRACE_INSN (cpu, "R%i = [I%i--];", reg, i);
3164       addr = IREG (i);
3165       if (DIS_ALGN_EXPT & 0x1)
3166 	addr &= ~3;
3167       dagsub (cpu, i, 4);
3168       STORE (DREG (reg), GET_LONG (addr));
3169     }
3170   else if (aop == 1 && W == 0 && m == 1)
3171     {
3172       TRACE_INSN (cpu, "R%i.L = W[I%i--];", reg, i);
3173       addr = IREG (i);
3174       dagsub (cpu, i, 2);
3175       STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | GET_WORD (addr));
3176     }
3177   else if (aop == 1 && W == 0 && m == 2)
3178     {
3179       TRACE_INSN (cpu, "R%i.H = W[I%i--];", reg, i);
3180       addr = IREG (i);
3181       dagsub (cpu, i, 2);
3182       STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (GET_WORD (addr) << 16));
3183     }
3184   else if (aop == 2 && W == 0 && m == 0)
3185     {
3186       TRACE_INSN (cpu, "R%i = [I%i];", reg, i);
3187       addr = IREG (i);
3188       if (DIS_ALGN_EXPT & 0x1)
3189 	addr &= ~3;
3190       STORE (DREG (reg), GET_LONG (addr));
3191     }
3192   else if (aop == 2 && W == 0 && m == 1)
3193     {
3194       TRACE_INSN (cpu, "R%i.L = W[I%i];", reg, i);
3195       addr = IREG (i);
3196       STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | GET_WORD (addr));
3197     }
3198   else if (aop == 2 && W == 0 && m == 2)
3199     {
3200       TRACE_INSN (cpu, "R%i.H = W[I%i];", reg, i);
3201       addr = IREG (i);
3202       STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (GET_WORD (addr) << 16));
3203     }
3204   else if (aop == 0 && W == 1 && m == 0)
3205     {
3206       TRACE_INSN (cpu, "[I%i++] = R%i;", i, reg);
3207       addr = IREG (i);
3208       dagadd (cpu, i, 4);
3209       PUT_LONG (addr, DREG (reg));
3210     }
3211   else if (aop == 0 && W == 1 && m == 1)
3212     {
3213       TRACE_INSN (cpu, "W[I%i++] = R%i.L;", i, reg);
3214       addr = IREG (i);
3215       dagadd (cpu, i, 2);
3216       PUT_WORD (addr, DREG (reg));
3217     }
3218   else if (aop == 0 && W == 1 && m == 2)
3219     {
3220       TRACE_INSN (cpu, "W[I%i++] = R%i.H;", i, reg);
3221       addr = IREG (i);
3222       dagadd (cpu, i, 2);
3223       PUT_WORD (addr, DREG (reg) >> 16);
3224     }
3225   else if (aop == 1 && W == 1 && m == 0)
3226     {
3227       TRACE_INSN (cpu, "[I%i--] = R%i;", i, reg);
3228       addr = IREG (i);
3229       dagsub (cpu, i, 4);
3230       PUT_LONG (addr, DREG (reg));
3231     }
3232   else if (aop == 1 && W == 1 && m == 1)
3233     {
3234       TRACE_INSN (cpu, "W[I%i--] = R%i.L;", i, reg);
3235       addr = IREG (i);
3236       dagsub (cpu, i, 2);
3237       PUT_WORD (addr, DREG (reg));
3238     }
3239   else if (aop == 1 && W == 1 && m == 2)
3240     {
3241       TRACE_INSN (cpu, "W[I%i--] = R%i.H;", i, reg);
3242       addr = IREG (i);
3243       dagsub (cpu, i, 2);
3244       PUT_WORD (addr, DREG (reg) >> 16);
3245     }
3246   else if (aop == 2 && W == 1 && m == 0)
3247     {
3248       TRACE_INSN (cpu, "[I%i] = R%i;", i, reg);
3249       addr = IREG (i);
3250       PUT_LONG (addr, DREG (reg));
3251     }
3252   else if (aop == 2 && W == 1 && m == 1)
3253     {
3254       TRACE_INSN (cpu, "W[I%i] = R%i.L;", i, reg);
3255       addr = IREG (i);
3256       PUT_WORD (addr, DREG (reg));
3257     }
3258   else if (aop == 2 && W == 1 && m == 2)
3259     {
3260       TRACE_INSN (cpu, "W[I%i] = R%i.H;", i, reg);
3261       addr = IREG (i);
3262       PUT_WORD (addr, DREG (reg) >> 16);
3263     }
3264   else if (aop == 3 && W == 0)
3265     {
3266       TRACE_INSN (cpu, "R%i = [I%i ++ M%i];", reg, i, m);
3267       addr = IREG (i);
3268       if (DIS_ALGN_EXPT & 0x1)
3269 	addr &= ~3;
3270       dagadd (cpu, i, MREG (m));
3271       STORE (DREG (reg), GET_LONG (addr));
3272     }
3273   else if (aop == 3 && W == 1)
3274     {
3275       TRACE_INSN (cpu, "[I%i ++ M%i] = R%i;", i, m, reg);
3276       addr = IREG (i);
3277       dagadd (cpu, i, MREG (m));
3278       PUT_LONG (addr, DREG (reg));
3279     }
3280   else
3281     illegal_instruction_or_combination (cpu);
3282 }
3283 
3284 static void
3285 decode_LDST_0 (SIM_CPU *cpu, bu16 iw0)
3286 {
3287   /* LDST
3288      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3289      | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
3290      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3291   int Z   = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
3292   int W   = ((iw0 >> LDST_W_bits) & LDST_W_mask);
3293   int sz  = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
3294   int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
3295   int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
3296   int ptr = ((iw0 >> LDST_ptr_bits) & LDST_ptr_mask);
3297   const char * const posts[] = { "++", "--", "", "<INV>" };
3298   const char *post = posts[aop];
3299   const char *ptr_name = get_preg_name (ptr);
3300 
3301   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDST);
3302   TRACE_EXTRACT (cpu, "%s: sz:%i W:%i aop:%i Z:%i ptr:%i reg:%i",
3303 		 __func__, sz, W, aop, Z, ptr, reg);
3304 
3305   if (aop == 3 || PARALLEL_GROUP == BFIN_PARALLEL_GROUP2)
3306     illegal_instruction_or_combination (cpu);
3307 
3308   if (W == 0)
3309     {
3310       if (sz == 0 && Z == 0)
3311 	{
3312 	  TRACE_INSN (cpu, "R%i = [%s%s];", reg, ptr_name, post);
3313 	  SET_DREG (reg, GET_LONG (PREG (ptr)));
3314 	}
3315       else if (sz == 0 && Z == 1)
3316 	{
3317 	  TRACE_INSN (cpu, "%s = [%s%s];", get_preg_name (reg), ptr_name, post);
3318 	  if (aop < 2 && ptr == reg)
3319 	    illegal_instruction_combination (cpu);
3320 	  SET_PREG (reg, GET_LONG (PREG (ptr)));
3321 	}
3322       else if (sz == 1 && Z == 0)
3323 	{
3324 	  TRACE_INSN (cpu, "R%i = W[%s%s] (Z);", reg, ptr_name, post);
3325 	  SET_DREG (reg, GET_WORD (PREG (ptr)));
3326 	}
3327       else if (sz == 1 && Z == 1)
3328 	{
3329 	  TRACE_INSN (cpu, "R%i = W[%s%s] (X);", reg, ptr_name, post);
3330 	  SET_DREG (reg, (bs32) (bs16) GET_WORD (PREG (ptr)));
3331 	}
3332       else if (sz == 2 && Z == 0)
3333 	{
3334 	  TRACE_INSN (cpu, "R%i = B[%s%s] (Z);", reg, ptr_name, post);
3335 	  SET_DREG (reg, GET_BYTE (PREG (ptr)));
3336 	}
3337       else if (sz == 2 && Z == 1)
3338 	{
3339 	  TRACE_INSN (cpu, "R%i = B[%s%s] (X);", reg, ptr_name, post);
3340 	  SET_DREG (reg, (bs32) (bs8) GET_BYTE (PREG (ptr)));
3341 	}
3342       else
3343 	illegal_instruction_or_combination (cpu);
3344     }
3345   else
3346     {
3347       if (sz == 0 && Z == 0)
3348 	{
3349 	  TRACE_INSN (cpu, "[%s%s] = R%i;", ptr_name, post, reg);
3350 	  PUT_LONG (PREG (ptr), DREG (reg));
3351 	}
3352       else if (sz == 0 && Z == 1)
3353 	{
3354 	  TRACE_INSN (cpu, "[%s%s] = %s;", ptr_name, post, get_preg_name (reg));
3355 	  PUT_LONG (PREG (ptr), PREG (reg));
3356 	}
3357       else if (sz == 1 && Z == 0)
3358 	{
3359 	  TRACE_INSN (cpu, "W[%s%s] = R%i;", ptr_name, post, reg);
3360 	  PUT_WORD (PREG (ptr), DREG (reg));
3361 	}
3362       else if (sz == 2 && Z == 0)
3363 	{
3364 	  TRACE_INSN (cpu, "B[%s%s] = R%i;", ptr_name, post, reg);
3365 	  PUT_BYTE (PREG (ptr), DREG (reg));
3366 	}
3367       else
3368 	illegal_instruction_or_combination (cpu);
3369     }
3370 
3371   if (aop == 0)
3372     SET_PREG (ptr, PREG (ptr) + (1 << (2 - sz)));
3373   if (aop == 1)
3374     SET_PREG (ptr, PREG (ptr) - (1 << (2 - sz)));
3375 }
3376 
3377 static void
3378 decode_LDSTiiFP_0 (SIM_CPU *cpu, bu16 iw0)
3379 {
3380   /* LDSTiiFP
3381      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3382      | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
3383      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3384   /* This isn't exactly a grp:reg as this insn only supports Dregs & Pregs,
3385      but for our usage, its functionality the same thing.  */
3386   int grp = ((iw0 >> 3) & 0x1);
3387   int reg = ((iw0 >> LDSTiiFP_reg_bits) & 0x7 /*LDSTiiFP_reg_mask*/);
3388   int offset = ((iw0 >> LDSTiiFP_offset_bits) & LDSTiiFP_offset_mask);
3389   int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
3390   bu32 imm = negimm5s4 (offset);
3391   bu32 ea = FPREG + imm;
3392   const char *imm_str = negimm5s4_str (offset);
3393   const char *reg_name = get_allreg_name (grp, reg);
3394 
3395   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTiiFP);
3396   TRACE_EXTRACT (cpu, "%s: W:%i offset:%#x grp:%i reg:%i", __func__,
3397 		 W, offset, grp, reg);
3398   TRACE_DECODE (cpu, "%s: negimm5s4:%#x", __func__, imm);
3399 
3400   if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2)
3401     illegal_instruction_or_combination (cpu);
3402 
3403   if (W == 0)
3404     {
3405       TRACE_INSN (cpu, "%s = [FP + %s];", reg_name, imm_str);
3406       reg_write (cpu, grp, reg, GET_LONG (ea));
3407     }
3408   else
3409     {
3410       TRACE_INSN (cpu, "[FP + %s] = %s;", imm_str, reg_name);
3411       PUT_LONG (ea, reg_read (cpu, grp, reg));
3412     }
3413 }
3414 
3415 static void
3416 decode_LDSTii_0 (SIM_CPU *cpu, bu16 iw0)
3417 {
3418   /* LDSTii
3419      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3420      | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
3421      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3422   int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
3423   int ptr = ((iw0 >> LDSTii_ptr_bit) & LDSTii_ptr_mask);
3424   int offset = ((iw0 >> LDSTii_offset_bit) & LDSTii_offset_mask);
3425   int op = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
3426   int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
3427   bu32 imm, ea;
3428   const char *imm_str;
3429   const char *ptr_name = get_preg_name (ptr);
3430 
3431   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTii);
3432   TRACE_EXTRACT (cpu, "%s: W:%i op:%i offset:%#x ptr:%i reg:%i",
3433 		 __func__, W, op, offset, ptr, reg);
3434 
3435   if (op == 0 || op == 3)
3436     imm = uimm4s4 (offset), imm_str = uimm4s4_str (offset);
3437   else
3438     imm = uimm4s2 (offset), imm_str = uimm4s2_str (offset);
3439   ea = PREG (ptr) + imm;
3440 
3441   TRACE_DECODE (cpu, "%s: uimm4s4/uimm4s2:%#x", __func__, imm);
3442 
3443   if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2)
3444     illegal_instruction_combination (cpu);
3445 
3446   if (W == 1 && op == 2)
3447     illegal_instruction (cpu);
3448 
3449   if (W == 0)
3450     {
3451       if (op == 0)
3452 	{
3453 	  TRACE_INSN (cpu, "R%i = [%s + %s];", reg, ptr_name, imm_str);
3454 	  SET_DREG (reg, GET_LONG (ea));
3455 	}
3456       else if (op == 1)
3457 	{
3458 	  TRACE_INSN (cpu, "R%i = W[%s + %s] (Z);", reg, ptr_name, imm_str);
3459 	  SET_DREG (reg, GET_WORD (ea));
3460 	}
3461       else if (op == 2)
3462 	{
3463 	  TRACE_INSN (cpu, "R%i = W[%s + %s] (X);", reg, ptr_name, imm_str);
3464 	  SET_DREG (reg, (bs32) (bs16) GET_WORD (ea));
3465 	}
3466       else if (op == 3)
3467 	{
3468 	  TRACE_INSN (cpu, "%s = [%s + %s];",
3469 		      get_preg_name (reg), ptr_name, imm_str);
3470 	  SET_PREG (reg, GET_LONG (ea));
3471 	}
3472     }
3473   else
3474     {
3475       if (op == 0)
3476 	{
3477 	  TRACE_INSN (cpu, "[%s + %s] = R%i;", ptr_name, imm_str, reg);
3478 	  PUT_LONG (ea, DREG (reg));
3479 	}
3480       else if (op == 1)
3481 	{
3482 	  TRACE_INSN (cpu, "W[%s + %s] = R%i;", ptr_name, imm_str, reg);
3483 	  PUT_WORD (ea, DREG (reg));
3484 	}
3485       else if (op == 3)
3486 	{
3487 	  TRACE_INSN (cpu, "[%s + %s] = %s;",
3488 		      ptr_name, imm_str, get_preg_name (reg));
3489 	  PUT_LONG (ea, PREG (reg));
3490 	}
3491     }
3492 }
3493 
3494 static void
3495 decode_LoopSetup_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1, bu32 pc)
3496 {
3497   /* LoopSetup
3498      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3499      | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |.rop...|.c.|.soffset.......|
3500      |.reg...........| - | - |.eoffset...............................|
3501      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3502   int c   = ((iw0 >> (LoopSetup_c_bits - 16)) & LoopSetup_c_mask);
3503   int reg = ((iw1 >> LoopSetup_reg_bits) & LoopSetup_reg_mask);
3504   int rop = ((iw0 >> (LoopSetup_rop_bits - 16)) & LoopSetup_rop_mask);
3505   int soffset = ((iw0 >> (LoopSetup_soffset_bits - 16)) & LoopSetup_soffset_mask);
3506   int eoffset = ((iw1 >> LoopSetup_eoffset_bits) & LoopSetup_eoffset_mask);
3507   int spcrel = pcrel4 (soffset);
3508   int epcrel = lppcrel10 (eoffset);
3509 
3510   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LoopSetup);
3511   TRACE_EXTRACT (cpu, "%s: rop:%i c:%i soffset:%i reg:%i eoffset:%i",
3512 		 __func__, rop, c, soffset, reg, eoffset);
3513   TRACE_DECODE (cpu, "%s: s_pcrel4:%#x e_lppcrel10:%#x",
3514 		__func__, spcrel, epcrel);
3515 
3516   if (reg > 7)
3517     illegal_instruction (cpu);
3518 
3519   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
3520     illegal_instruction_combination (cpu);
3521 
3522   if (rop == 0)
3523     {
3524       TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i;", spcrel, epcrel, c);
3525     }
3526   else if (rop == 1 && reg <= 7)
3527     {
3528       TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i = %s;",
3529 		  spcrel, epcrel, c, get_preg_name (reg));
3530       SET_LCREG (c, PREG (reg));
3531     }
3532   else if (rop == 3 && reg <= 7)
3533     {
3534       TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i = %s >> 1;",
3535 		  spcrel, epcrel, c, get_preg_name (reg));
3536       SET_LCREG (c, PREG (reg) >> 1);
3537     }
3538   else
3539     illegal_instruction (cpu);
3540 
3541   SET_LTREG (c, pc + spcrel);
3542   SET_LBREG (c, pc + epcrel);
3543 }
3544 
3545 static void
3546 decode_LDIMMhalf_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3547 {
3548   /* LDIMMhalf
3549      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3550      | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |.Z.|.H.|.S.|.grp...|.reg.......|
3551      |.hword.........................................................|
3552      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3553   int H = ((iw0 >> (LDIMMhalf_H_bits - 16)) & LDIMMhalf_H_mask);
3554   int Z = ((iw0 >> (LDIMMhalf_Z_bits - 16)) & LDIMMhalf_Z_mask);
3555   int S = ((iw0 >> (LDIMMhalf_S_bits - 16)) & LDIMMhalf_S_mask);
3556   int reg = ((iw0 >> (LDIMMhalf_reg_bits - 16)) & LDIMMhalf_reg_mask);
3557   int grp = ((iw0 >> (LDIMMhalf_grp_bits - 16)) & LDIMMhalf_grp_mask);
3558   int hword = ((iw1 >> LDIMMhalf_hword_bits) & LDIMMhalf_hword_mask);
3559   bu32 val;
3560   const char *val_str;
3561   const char *reg_name = get_allreg_name (grp, reg);
3562 
3563   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDIMMhalf);
3564   TRACE_EXTRACT (cpu, "%s: Z:%i H:%i S:%i grp:%i reg:%i hword:%#x",
3565 		 __func__, Z, H, S, grp, reg, hword);
3566 
3567   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
3568     illegal_instruction_combination (cpu);
3569 
3570   if (S == 1)
3571     val = imm16 (hword), val_str = imm16_str (hword);
3572   else
3573     val = luimm16 (hword), val_str = luimm16_str (hword);
3574 
3575   if (H == 0 && S == 1 && Z == 0)
3576     {
3577       TRACE_INSN (cpu, "%s = %s (X);", reg_name, val_str);
3578     }
3579   else if (H == 0 && S == 0 && Z == 1)
3580     {
3581       TRACE_INSN (cpu, "%s = %s (Z);", reg_name, val_str);
3582     }
3583   else if (H == 0 && S == 0 && Z == 0)
3584     {
3585       TRACE_INSN (cpu, "%s.L = %s;", reg_name, val_str);
3586       val = REG_H_L (reg_read (cpu, grp, reg), val);
3587     }
3588   else if (H == 1 && S == 0 && Z == 0)
3589     {
3590       TRACE_INSN (cpu, "%s.H = %s;", reg_name, val_str);
3591       val = REG_H_L (val << 16, reg_read (cpu, grp, reg));
3592     }
3593   else
3594     illegal_instruction (cpu);
3595 
3596   reg_write (cpu, grp, reg, val);
3597 }
3598 
3599 static void
3600 decode_CALLa_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1, bu32 pc)
3601 {
3602   /* CALLa
3603      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3604      | 1 | 1 | 1 | 0 | 0 | 0 | 1 |.S.|.msw...........................|
3605      |.lsw...........................................................|
3606      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3607   int S   = ((iw0 >> (CALLa_S_bits - 16)) & CALLa_S_mask);
3608   int lsw = ((iw1 >> 0) & 0xffff);
3609   int msw = ((iw0 >> 0) & 0xff);
3610   int pcrel = pcrel24 ((msw << 16) | lsw);
3611   bu32 newpc = pc + pcrel;
3612 
3613   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CALLa);
3614   TRACE_EXTRACT (cpu, "%s: S:%i msw:%#x lsw:%#x", __func__, S, msw, lsw);
3615   TRACE_DECODE (cpu, "%s: pcrel24:%#x", __func__, pcrel);
3616 
3617   TRACE_INSN (cpu, "%s %#x;", S ? "CALL" : "JUMP.L", pcrel);
3618 
3619   if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
3620     illegal_instruction_combination (cpu);
3621 
3622   if (S == 1)
3623     {
3624       BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "CALL");
3625       SET_RETSREG (hwloop_get_next_pc (cpu, pc, 4));
3626     }
3627   else
3628     BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.L");
3629 
3630   SET_PCREG (newpc);
3631   BFIN_CPU_STATE.did_jump = true;
3632   PROFILE_BRANCH_TAKEN (cpu);
3633   CYCLE_DELAY = 5;
3634 }
3635 
3636 static void
3637 decode_LDSTidxI_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3638 {
3639   /* LDSTidxI
3640      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3641      | 1 | 1 | 1 | 0 | 0 | 1 |.W.|.Z.|.sz....|.ptr.......|.reg.......|
3642      |.offset........................................................|
3643      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3644   int Z = ((iw0 >> (LDSTidxI_Z_bits - 16)) & LDSTidxI_Z_mask);
3645   int W = ((iw0 >> (LDSTidxI_W_bits - 16)) & LDSTidxI_W_mask);
3646   int sz = ((iw0 >> (LDSTidxI_sz_bits - 16)) & LDSTidxI_sz_mask);
3647   int reg = ((iw0 >> (LDSTidxI_reg_bits - 16)) & LDSTidxI_reg_mask);
3648   int ptr = ((iw0 >> (LDSTidxI_ptr_bits - 16)) & LDSTidxI_ptr_mask);
3649   int offset = ((iw1 >> LDSTidxI_offset_bits) & LDSTidxI_offset_mask);
3650   const char *ptr_name = get_preg_name (ptr);
3651   bu32 imm_16s4 = imm16s4 (offset);
3652   bu32 imm_16s2 = imm16s2 (offset);
3653   bu32 imm_16 = imm16 (offset);
3654 
3655   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTidxI);
3656   TRACE_EXTRACT (cpu, "%s: W:%i Z:%i sz:%i ptr:%i reg:%i offset:%#x",
3657 		 __func__, W, Z, sz, ptr, reg, offset);
3658 
3659   if (sz == 3)
3660     illegal_instruction (cpu);
3661 
3662   if (W == 0)
3663     {
3664       if (sz == 0 && Z == 0)
3665 	{
3666 	  TRACE_INSN (cpu, "R%i = [%s + %s];",
3667 		      reg, ptr_name, imm16s4_str (offset));
3668 	  SET_DREG (reg, GET_LONG (PREG (ptr) + imm_16s4));
3669 	}
3670       else if (sz == 0 && Z == 1)
3671 	{
3672 	  TRACE_INSN (cpu, "%s = [%s + %s];",
3673 		      get_preg_name (reg), ptr_name, imm16s4_str (offset));
3674 	  SET_PREG (reg, GET_LONG (PREG (ptr) + imm_16s4));
3675 	}
3676       else if (sz == 1 && Z == 0)
3677 	{
3678 	  TRACE_INSN (cpu, "R%i = W[%s + %s] (Z);",
3679 		      reg, ptr_name, imm16s2_str (offset));
3680 	  SET_DREG (reg, GET_WORD (PREG (ptr) + imm_16s2));
3681 	}
3682       else if (sz == 1 && Z == 1)
3683 	{
3684 	  TRACE_INSN (cpu, "R%i = W[%s + %s] (X);",
3685 		      reg, ptr_name, imm16s2_str (offset));
3686 	  SET_DREG (reg, (bs32) (bs16) GET_WORD (PREG (ptr) + imm_16s2));
3687 	}
3688       else if (sz == 2 && Z == 0)
3689 	{
3690 	  TRACE_INSN (cpu, "R%i = B[%s + %s] (Z);",
3691 		      reg, ptr_name, imm16_str (offset));
3692 	  SET_DREG (reg, GET_BYTE (PREG (ptr) + imm_16));
3693 	}
3694       else if (sz == 2 && Z == 1)
3695 	{
3696 	  TRACE_INSN (cpu, "R%i = B[%s + %s] (X);",
3697 		      reg, ptr_name, imm16_str (offset));
3698 	  SET_DREG (reg, (bs32) (bs8) GET_BYTE (PREG (ptr) + imm_16));
3699 	}
3700     }
3701   else
3702     {
3703       if (sz != 0 && Z != 0)
3704 	illegal_instruction (cpu);
3705 
3706       if (sz == 0 && Z == 0)
3707 	{
3708 	  TRACE_INSN (cpu, "[%s + %s] = R%i;", ptr_name,
3709 		      imm16s4_str (offset), reg);
3710 	  PUT_LONG (PREG (ptr) + imm_16s4, DREG (reg));
3711 	}
3712       else if (sz == 0 && Z == 1)
3713 	{
3714 	  TRACE_INSN (cpu, "[%s + %s] = %s;",
3715 		      ptr_name, imm16s4_str (offset), get_preg_name (reg));
3716 	  PUT_LONG (PREG (ptr) + imm_16s4, PREG (reg));
3717 	}
3718       else if (sz == 1 && Z == 0)
3719 	{
3720 	  TRACE_INSN (cpu, "W[%s + %s] = R%i;",
3721 		      ptr_name, imm16s2_str (offset), reg);
3722 	  PUT_WORD (PREG (ptr) + imm_16s2, DREG (reg));
3723 	}
3724       else if (sz == 2 && Z == 0)
3725 	{
3726 	  TRACE_INSN (cpu, "B[%s + %s] = R%i;",
3727 		      ptr_name, imm16_str (offset), reg);
3728 	  PUT_BYTE (PREG (ptr) + imm_16, DREG (reg));
3729 	}
3730     }
3731 }
3732 
3733 static void
3734 decode_linkage_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3735 {
3736   /* linkage
3737      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3738      | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.R.|
3739      |.framesize.....................................................|
3740      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3741   int R = ((iw0 >> (Linkage_R_bits - 16)) & Linkage_R_mask);
3742   int framesize = ((iw1 >> Linkage_framesize_bits) & Linkage_framesize_mask);
3743   bu32 sp;
3744 
3745   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_linkage);
3746   TRACE_EXTRACT (cpu, "%s: R:%i framesize:%#x", __func__, R, framesize);
3747 
3748   if (R == 0)
3749     {
3750       int size = uimm16s4 (framesize);
3751       sp = SPREG;
3752       TRACE_INSN (cpu, "LINK %s;", uimm16s4_str (framesize));
3753       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
3754 	illegal_instruction_combination (cpu);
3755       sp -= 4;
3756       PUT_LONG (sp, RETSREG);
3757       sp -= 4;
3758       PUT_LONG (sp, FPREG);
3759       SET_FPREG (sp);
3760       sp -= size;
3761       CYCLE_DELAY = 3;
3762     }
3763   else
3764     {
3765       /* Restore SP from FP.  */
3766       sp = FPREG;
3767       TRACE_INSN (cpu, "UNLINK;");
3768       if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
3769 	illegal_instruction_combination (cpu);
3770       SET_FPREG (GET_LONG (sp));
3771       sp += 4;
3772       SET_RETSREG (GET_LONG (sp));
3773       sp += 4;
3774       CYCLE_DELAY = 2;
3775     }
3776 
3777   SET_SPREG (sp);
3778 }
3779 
3780 static void
3781 decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3782 {
3783   /* dsp32mac
3784      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3785      | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
3786      |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
3787      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3788   int op1  = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
3789   int w1   = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
3790   int P    = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
3791   int MM   = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
3792   int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
3793   int M    = ((iw0 >> (DSP32Mac_M_bits - 16)) & DSP32Mac_M_mask);
3794   int w0   = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
3795   int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
3796   int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
3797   int dst  = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
3798   int h10  = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
3799   int h00  = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
3800   int op0  = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
3801   int h11  = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
3802   int h01  = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
3803 
3804   bu32 res = DREG (dst);
3805   bu32 v_0 = 0, v_1 = 0, zero = 0, n_1 = 0, n_0 = 0;
3806 
3807   static const char * const ops[] = { "=", "+=", "-=" };
3808   char _buf[128], *buf = _buf;
3809   int _MM = MM;
3810 
3811   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mac);
3812   TRACE_EXTRACT (cpu, "%s: M:%i mmod:%i MM:%i P:%i w1:%i op1:%i h01:%i h11:%i "
3813 		      "w0:%i op0:%i h00:%i h10:%i dst:%i src0:%i src1:%i",
3814 		 __func__, M, mmod, MM, P, w1, op1, h01, h11, w0, op0, h00, h10,
3815 		 dst, src0, src1);
3816 
3817   if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3)
3818     illegal_instruction (cpu);
3819 
3820   if ((w1 || w0) && mmod == M_W32)
3821     illegal_instruction (cpu);
3822 
3823   if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0)
3824     illegal_instruction (cpu);
3825 
3826   /* First handle MAC1 side.  */
3827   if (w1 == 1 || op1 != 3)
3828     {
3829       bu32 res1 = decode_macfunc (cpu, 1, op1, h01, h11, src0,
3830 				  src1, mmod, MM, P, &v_1, &n_1);
3831 
3832       if (w1)
3833 	buf += sprintf (buf, P ? "R%i" : "R%i.H", dst + P);
3834 
3835       if (op1 == 3)
3836 	{
3837 	  buf += sprintf (buf, " = A1");
3838 	  zero = !!(res1 == 0);
3839 	}
3840       else
3841 	{
3842 	  if (w1)
3843 	    buf += sprintf (buf, " = (");
3844 	  buf += sprintf (buf, "A1 %s R%i.%c * R%i.%c", ops[op1],
3845 			  src0, h01 ? 'H' : 'L',
3846 			  src1, h11 ? 'H' : 'L');
3847 	  if (w1)
3848 	    buf += sprintf (buf, ")");
3849 	}
3850 
3851       if (w1)
3852 	{
3853 	  if (P)
3854 	    STORE (DREG (dst + 1), res1);
3855 	  else
3856 	    {
3857 	      if (res1 & 0xffff0000)
3858 		illegal_instruction (cpu);
3859 	      res = REG_H_L (res1 << 16, res);
3860 	    }
3861 	}
3862       else
3863 	v_1 = 0;
3864 
3865       if (w0 == 1 || op0 != 3)
3866 	{
3867 	  if (_MM)
3868 	    buf += sprintf (buf, " (M)");
3869 	  _MM = 0;
3870 	  buf += sprintf (buf, ", ");
3871 	}
3872     }
3873 
3874   /* Then handle MAC0 side.  */
3875   if (w0 == 1 || op0 != 3)
3876     {
3877       bu32 res0 = decode_macfunc (cpu, 0, op0, h00, h10, src0,
3878 				  src1, mmod, 0, P, &v_0, &n_0);
3879 
3880       if (w0)
3881 	buf += sprintf (buf, P ? "R%i" : "R%i.L", dst);
3882 
3883       if (op0 == 3)
3884 	{
3885 	  buf += sprintf (buf, " = A0");
3886 	  zero |= !!(res0 == 0);
3887 	}
3888       else
3889 	{
3890 	  if (w0)
3891 	    buf += sprintf (buf, " = (");
3892 	  buf += sprintf (buf, "A0 %s R%i.%c * R%i.%c", ops[op0],
3893 			  src0, h00 ? 'H' : 'L',
3894 			  src1, h10 ? 'H' : 'L');
3895 	  if (w0)
3896 	    buf += sprintf (buf, ")");
3897 	}
3898 
3899       if (w0)
3900 	{
3901 	  if (P)
3902 	    STORE (DREG (dst), res0);
3903 	  else
3904 	    {
3905 	      if (res0 & 0xffff0000)
3906 		illegal_instruction (cpu);
3907 	      res = REG_H_L (res, res0);
3908 	    }
3909 	}
3910       else
3911 	v_0 = 0;
3912     }
3913 
3914   TRACE_INSN (cpu, "%s%s;", _buf, mac_optmode (mmod, _MM));
3915 
3916   if (!P && (w0 || w1))
3917     {
3918       STORE (DREG (dst), res);
3919       SET_ASTATREG (v, v_0 | v_1);
3920       if (v_0 || v_1)
3921 	SET_ASTATREG (vs, 1);
3922     }
3923   else if (P)
3924     {
3925       SET_ASTATREG (v, v_0 | v_1);
3926       if (v_0 || v_1)
3927 	SET_ASTATREG (vs, 1);
3928     }
3929 
3930   if ((w0 == 1 && op0 == 3) || (w1 == 1 && op1 == 3))
3931     {
3932       SET_ASTATREG (az, zero);
3933       if (!(w0 == 1 && op0 == 3))
3934 	n_0 = 0;
3935       if (!(w1 == 1 && op1 == 3))
3936 	n_1 = 0;
3937       SET_ASTATREG (an, n_1 | n_0);
3938     }
3939 }
3940 
3941 static void
3942 decode_dsp32mult_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3943 {
3944   /* dsp32mult
3945      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3946      | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
3947      |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
3948      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
3949   int op1  = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
3950   int w1   = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
3951   int P    = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
3952   int MM   = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
3953   int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
3954   int M    = ((iw0 >> (DSP32Mac_M_bits - 16)) & DSP32Mac_M_mask);
3955   int w0   = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
3956   int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
3957   int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
3958   int dst  = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
3959   int h10  = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
3960   int h00  = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
3961   int op0  = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
3962   int h11  = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
3963   int h01  = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
3964 
3965   bu32 res = DREG (dst);
3966   bu32 sat0 = 0, sat1 = 0, v_i0 = 0, v_i1 = 0;
3967   char _buf[128], *buf = _buf;
3968   int _MM = MM;
3969 
3970   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mult);
3971   TRACE_EXTRACT (cpu, "%s: M:%i mmod:%i MM:%i P:%i w1:%i op1:%i h01:%i h11:%i "
3972 		      "w0:%i op0:%i h00:%i h10:%i dst:%i src0:%i src1:%i",
3973 		 __func__, M, mmod, MM, P, w1, op1, h01, h11, w0, op0, h00, h10,
3974 		 dst, src0, src1);
3975 
3976   if (w1 == 0 && w0 == 0)
3977     illegal_instruction (cpu);
3978   if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0)
3979     illegal_instruction (cpu);
3980   if (P && ((dst & 1) || (op1 != 0) || (op0 != 0) || !is_macmod_pmove (mmod)))
3981     illegal_instruction (cpu);
3982   if (!P && ((op1 != 0) || (op0 != 0) || !is_macmod_hmove (mmod)))
3983     illegal_instruction (cpu);
3984 
3985   /* First handle MAC1 side.  */
3986   if (w1)
3987     {
3988       bu64 r = decode_multfunc (cpu, h01, h11, src0, src1, mmod, MM, &sat1);
3989       bu32 res1 = extract_mult (cpu, r, mmod, MM, P, &v_i1);
3990 
3991       buf += sprintf (buf, P ? "R%i" : "R%i.H", dst + P);
3992       buf += sprintf (buf, " = R%i.%c * R%i.%c",
3993 		      src0, h01 ? 'H' : 'L',
3994 		      src1, h11 ? 'H' : 'L');
3995       if (w0)
3996 	{
3997 	  if (_MM)
3998 	    buf += sprintf (buf, " (M)");
3999 	  _MM = 0;
4000 	  buf += sprintf (buf, ", ");
4001 	}
4002 
4003       if (P)
4004 	STORE (DREG (dst + 1), res1);
4005       else
4006 	{
4007 	  if (res1 & 0xFFFF0000)
4008 	    illegal_instruction (cpu);
4009 	  res = REG_H_L (res1 << 16, res);
4010 	}
4011     }
4012 
4013   /* First handle MAC0 side.  */
4014   if (w0)
4015     {
4016       bu64 r = decode_multfunc (cpu, h00, h10, src0, src1, mmod, 0, &sat0);
4017       bu32 res0 = extract_mult (cpu, r, mmod, 0, P, &v_i0);
4018 
4019       buf += sprintf (buf, P ? "R%i" : "R%i.L", dst);
4020       buf += sprintf (buf, " = R%i.%c * R%i.%c",
4021 		      src0, h01 ? 'H' : 'L',
4022 		      src1, h11 ? 'H' : 'L');
4023 
4024       if (P)
4025 	STORE (DREG (dst), res0);
4026       else
4027 	{
4028 	  if (res0 & 0xFFFF0000)
4029 	    illegal_instruction (cpu);
4030 	  res = REG_H_L (res, res0);
4031 	}
4032     }
4033 
4034   TRACE_INSN (cpu, "%s%s;", _buf, mac_optmode (mmod, _MM));
4035 
4036   if (!P && (w0 || w1))
4037     STORE (DREG (dst), res);
4038 
4039   if (w0 || w1)
4040     {
4041       bu32 v = sat0 | sat1 | v_i0 | v_i1;
4042 
4043       STORE (ASTATREG (v), v);
4044       STORE (ASTATREG (v_copy), v);
4045       if (v)
4046 	STORE (ASTATREG (vs), v);
4047     }
4048 }
4049 
4050 static void
4051 decode_dsp32alu_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
4052 {
4053   /* dsp32alu
4054      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
4055      | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
4056      |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
4057      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
4058   int s    = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
4059   int x    = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
4060   int aop  = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
4061   int src0 = ((iw1 >> DSP32Alu_src0_bits) & DSP32Alu_src0_mask);
4062   int src1 = ((iw1 >> DSP32Alu_src1_bits) & DSP32Alu_src1_mask);
4063   int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
4064   int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
4065   int M    = ((iw0 >> (DSP32Alu_M_bits - 16)) & DSP32Alu_M_mask);
4066   int HL   = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
4067   int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
4068 
4069   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32alu);
4070   TRACE_EXTRACT (cpu, "%s: M:%i HL:%i aopcde:%i aop:%i s:%i x:%i dst0:%i "
4071 		      "dst1:%i src0:%i src1:%i",
4072 		 __func__, M, HL, aopcde, aop, s, x, dst0, dst1, src0, src1);
4073 
4074   if ((aop == 0 || aop == 2) && aopcde == 9 && x == 0 && s == 0 && HL == 0)
4075     {
4076       int a = aop >> 1;
4077       TRACE_INSN (cpu, "A%i.L = R%i.L;", a, src0);
4078       SET_AWREG (a, REG_H_L (AWREG (a), DREG (src0)));
4079     }
4080   else if ((aop == 0 || aop == 2) && aopcde == 9 && x == 0 && s == 0 && HL == 1)
4081     {
4082       int a = aop >> 1;
4083       TRACE_INSN (cpu, "A%i.H = R%i.H;", a, src0);
4084       SET_AWREG (a, REG_H_L (DREG (src0), AWREG (a)));
4085     }
4086   else if ((aop == 1 || aop == 0) && aopcde == 5 && x == 0 && s == 0)
4087     {
4088       bs32 val0 = DREG (src0);
4089       bs32 val1 = DREG (src1);
4090       bs32 res;
4091       bs32 signRes;
4092       bs32 ovX, sBit1, sBit2, sBitRes1, sBitRes2;
4093 
4094       TRACE_INSN (cpu, "R%i.%s = R%i %s R%i (RND12)", dst0, HL ? "L" : "H",
4095 		  src0, aop & 0x1 ? "-" : "+", src1);
4096 
4097       /* If subtract, just invert and add one.  */
4098       if (aop & 0x1)
4099 	{
4100 	  if (val1 == 0x80000000)
4101 	    val1 = 0x7FFFFFFF;
4102 	  else
4103 	    val1 = ~val1 + 1;
4104 	}
4105 
4106       /* Get the sign bits, since we need them later.  */
4107       sBit1 = !!(val0 & 0x80000000);
4108       sBit2 = !!(val1 & 0x80000000);
4109 
4110       res = val0 + val1;
4111 
4112       sBitRes1 = !!(res & 0x80000000);
4113       /* Round to the 12th bit.  */
4114       res += 0x0800;
4115       sBitRes2 = !!(res & 0x80000000);
4116 
4117       signRes = res;
4118       signRes >>= 27;
4119 
4120       /* Overflow if
4121            pos + pos = neg
4122            neg + neg = pos
4123            positive_res + positive_round = neg
4124          Shift and upper 4 bits where not the same.  */
4125       if ((!(sBit1 ^ sBit2) && (sBit1 ^ sBitRes1))
4126 	  || (!sBit1 && !sBit2 && sBitRes2)
4127 	  || ((signRes != 0) && (signRes != -1)))
4128 	{
4129 	  /* Both X1 and X2 Neg res is neg overflow.  */
4130 	  if (sBit1 && sBit2)
4131 	    res = 0x80000000;
4132 	  /* Both X1 and X2 Pos res is pos overflow.  */
4133 	  else if (!sBit1 && !sBit2)
4134 	    res = 0x7FFFFFFF;
4135 	  /* Pos+Neg or Neg+Pos take the sign of the result.  */
4136 	  else if (sBitRes1)
4137 	    res = 0x80000000;
4138 	  else
4139 	    res = 0x7FFFFFFF;
4140 
4141 	  ovX = 1;
4142 	}
4143       else
4144 	{
4145 	  /* Shift up now after overflow detection.  */
4146 	  ovX = 0;
4147 	  res <<= 4;
4148 	}
4149 
4150       res >>= 16;
4151 
4152       if (HL)
4153 	STORE (DREG (dst0), REG_H_L (res << 16, DREG (dst0)));
4154       else
4155 	STORE (DREG (dst0), REG_H_L (DREG (dst0), res));
4156 
4157       SET_ASTATREG (az, res == 0);
4158       SET_ASTATREG (an, res & 0x8000);
4159       SET_ASTATREG (v, ovX);
4160       if (ovX)
4161 	SET_ASTATREG (vs, ovX);
4162     }
4163   else if ((aop == 2 || aop == 3) && aopcde == 5 && x == 1 && s == 0)
4164     {
4165       bs32 val0 = DREG (src0);
4166       bs32 val1 = DREG (src1);
4167       bs32 res;
4168 
4169       TRACE_INSN (cpu, "R%i.%s = R%i %s R%i (RND20)", dst0, HL ? "L" : "H",
4170 		  src0, aop & 0x1 ? "-" : "+", src1);
4171 
4172       /* If subtract, just invert and add one.  */
4173       if (aop & 0x1)
4174 	val1 = ~val1 + 1;
4175 
4176       res = (val0 >> 4) + (val1 >> 4) + (((val0 & 0xf) + (val1 & 0xf)) >> 4);
4177       res += 0x8000;
4178       /* Don't sign extend during the shift.  */
4179       res = ((bu32)res >> 16);
4180 
4181       /* Don't worry about overflows, since we are shifting right.  */
4182 
4183       if (HL)
4184 	STORE (DREG (dst0), REG_H_L (res << 16, DREG (dst0)));
4185       else
4186 	STORE (DREG (dst0), REG_H_L (DREG (dst0), res));
4187 
4188       SET_ASTATREG (az, res == 0);
4189       SET_ASTATREG (an, res & 0x8000);
4190       SET_ASTATREG (v, 0);
4191     }
4192   else if ((aopcde == 2 || aopcde == 3) && x == 0)
4193     {
4194       bu32 s1, s2, val, ac0_i = 0, v_i = 0;
4195 
4196       TRACE_INSN (cpu, "R%i.%c = R%i.%c %c R%i.%c%s;",
4197 		  dst0, HL ? 'H' : 'L',
4198 		  src0, aop & 2 ? 'H' : 'L',
4199 		  aopcde == 2 ? '+' : '-',
4200 		  src1, aop & 1 ? 'H' : 'L',
4201 		  amod1 (s, x));
4202 
4203       s1 = DREG (src0);
4204       s2 = DREG (src1);
4205       if (aop & 1)
4206 	s2 >>= 16;
4207       if (aop & 2)
4208 	s1 >>= 16;
4209 
4210       if (aopcde == 2)
4211 	val = add16 (cpu, s1, s2, &ac0_i, &v_i, 0, 0, s, 0);
4212       else
4213 	val = sub16 (cpu, s1, s2, &ac0_i, &v_i, 0, 0, s, 0);
4214 
4215       SET_ASTATREG (ac0, ac0_i);
4216       SET_ASTATREG (v, v_i);
4217       if (v_i)
4218 	SET_ASTATREG (vs, v_i);
4219 
4220       if (HL)
4221 	SET_DREG_H (dst0, val << 16);
4222       else
4223 	SET_DREG_L (dst0, val);
4224 
4225       SET_ASTATREG (an, val & 0x8000);
4226       SET_ASTATREG (az, val == 0);
4227     }
4228   else if ((aop == 0 || aop == 2) && aopcde == 9 && x == 0 && s == 1 && HL == 0)
4229     {
4230       int a = aop >> 1;
4231       TRACE_INSN (cpu, "A%i = R%i;", a, src0);
4232       SET_AREG32 (a, DREG (src0));
4233     }
4234   else if ((aop == 1 || aop == 3) && aopcde == 9 && x == 0 && s == 0 && HL == 0)
4235     {
4236       int a = aop >> 1;
4237       TRACE_INSN (cpu, "A%i.X = R%i.L;", a, src0);
4238       SET_AXREG (a, (bs8)DREG (src0));
4239     }
4240   else if (aop == 3 && aopcde == 11 && x == 0 && HL == 0)
4241     {
4242       bu64 acc0 = get_extended_acc (cpu, 0);
4243       bu64 acc1 = get_extended_acc (cpu, 1);
4244       bu32 carry = (bu40)acc1 < (bu40)acc0;
4245       bu32 sat = 0;
4246 
4247       TRACE_INSN (cpu, "A0 -= A1%s;", s ? " (W32)" : "");
4248 
4249       acc0 -= acc1;
4250       if ((bs64)acc0 < -0x8000000000ll)
4251 	acc0 = -0x8000000000ull, sat = 1;
4252       else if ((bs64)acc0 >= 0x7fffffffffll)
4253 	acc0 = 0x7fffffffffull, sat = 1;
4254 
4255       if (s == 1)
4256 	{
4257 	  /* A0 -= A1 (W32)  */
4258 	  if (acc0 & (bu64)0x8000000000ll)
4259 	    acc0 &= 0x80ffffffffll, sat = 1;
4260 	  else
4261 	    acc0 &= 0xffffffffll;
4262 	}
4263       STORE (AXREG (0), (acc0 >> 32) & 0xff);
4264       STORE (AWREG (0), acc0 & 0xffffffff);
4265       STORE (ASTATREG (az), acc0 == 0);
4266       STORE (ASTATREG (an), !!(acc0 & (bu64)0x8000000000ll));
4267       STORE (ASTATREG (ac0), carry);
4268       STORE (ASTATREG (ac0_copy), carry);
4269       STORE (ASTATREG (av0), sat);
4270       if (sat)
4271 	STORE (ASTATREG (av0s), sat);
4272     }
4273   else if ((aop == 0 || aop == 1) && aopcde == 22 && x == 0)
4274     {
4275       bu32 s0, s0L, s0H, s1, s1L, s1H;
4276       bu32 tmp0, tmp1, i;
4277       const char * const opts[] = { "rndl", "rndh", "tl", "th" };
4278 
4279       TRACE_INSN (cpu, "R%i = BYTEOP2P (R%i:%i, R%i:%i) (%s%s);", dst0,
4280 		  src0 + 1, src0, src1 + 1, src1, opts[HL + (aop << 1)],
4281 		  s ? ", r" : "");
4282 
4283       if ((src1 != 0 && src1 != 2) || (src0 != 0 && src0 != 2))
4284 	illegal_instruction (cpu);
4285 
4286       s0L = DREG (src0);
4287       s0H = DREG (src0 + 1);
4288       s1L = DREG (src1);
4289       s1H = DREG (src1 + 1);
4290       if (s)
4291 	{
4292 	  s0 = algn (s0H, s0L, IREG (0) & 3);
4293 	  s1 = algn (s1H, s1L, IREG (0) & 3);
4294 	}
4295       else
4296 	{
4297 	  s0 = algn (s0L, s0H, IREG (0) & 3);
4298 	  s1 = algn (s1L, s1H, IREG (0) & 3);
4299 	}
4300 
4301       i = !aop * 2;
4302       tmp0 = ((((s1 >>  8) & 0xff) + ((s1 >>  0) & 0xff) +
4303 	       ((s0 >>  8) & 0xff) + ((s0 >>  0) & 0xff) + i) >> 2) & 0xff;
4304       tmp1 = ((((s1 >> 24) & 0xff) + ((s1 >> 16) & 0xff) +
4305 	       ((s0 >> 24) & 0xff) + ((s0 >> 16) & 0xff) + i) >> 2) & 0xff;
4306       STORE (DREG (dst0), (tmp1 << (16 + (HL * 8))) | (tmp0 << (HL * 8)));
4307 
4308       /* Implicit DISALGNEXCPT in parallel.  */
4309       DIS_ALGN_EXPT |= 1;
4310     }
4311   else if ((aop == 0 || aop == 1) && aopcde == 8 && x == 0 && s == 0 && HL == 0)
4312     {
4313       TRACE_INSN (cpu, "A%i = 0;", aop);
4314       SET_AREG (aop, 0);
4315     }
4316   else if (aop == 2 && aopcde == 8 && x == 0 && s == 0 && HL == 0)
4317     {
4318       TRACE_INSN (cpu, "A1 = A0 = 0;");
4319       SET_AREG (0, 0);
4320       SET_AREG (1, 0);
4321     }
4322   else if ((aop == 0 || aop == 1 || aop == 2) && s == 1 && aopcde == 8
4323 	   && x == 0 && HL == 0)
4324     {
4325       bs40 acc0 = get_extended_acc (cpu, 0);
4326       bs40 acc1 = get_extended_acc (cpu, 1);
4327       bu32 sat;
4328 
4329       if (aop == 0 || aop == 1)
4330 	TRACE_INSN (cpu, "A%i = A%i (S);", aop, aop);
4331       else
4332 	TRACE_INSN (cpu, "A1 = A1 (S), A0 = A0 (S);");
4333 
4334       if (aop == 0 || aop == 2)
4335 	{
4336 	  sat = 0;
4337 	  acc0 = saturate_s32 (acc0, &sat);
4338 	  acc0 |= -(acc0 & 0x80000000ull);
4339 	  SET_AXREG (0, (acc0 >> 31) & 0xFF);
4340 	  SET_AWREG (0, acc0 & 0xFFFFFFFF);
4341 	  SET_ASTATREG (av0, sat);
4342 	  if (sat)
4343 	    SET_ASTATREG (av0s, sat);
4344 	}
4345       else
4346 	acc0 = 1;
4347 
4348       if (aop == 1 || aop == 2)
4349 	{
4350 	  sat = 0;
4351 	  acc1 = saturate_s32 (acc1, &sat);
4352 	  acc1 |= -(acc1 & 0x80000000ull);
4353 	  SET_AXREG (1, (acc1 >> 31) & 0xFF);
4354 	  SET_AWREG (1, acc1 & 0xFFFFFFFF);
4355 	  SET_ASTATREG (av1, sat);
4356 	  if (sat)
4357 	    SET_ASTATREG (av1s, sat);
4358 	}
4359       else
4360 	acc1 = 1;
4361 
4362       SET_ASTATREG (az, (acc0 == 0) || (acc1 == 0));
4363       SET_ASTATREG (an, ((acc0 >> 31) & 1) || ((acc1 >> 31) & 1));
4364     }
4365   else if (aop == 3 && aopcde == 8 && x == 0 && HL == 0)
4366     {
4367       TRACE_INSN (cpu, "A%i = A%i;", s, !s);
4368       SET_AXREG (s, AXREG (!s));
4369       SET_AWREG (s, AWREG (!s));
4370     }
4371   else if (aop == 3 && HL == 0 && aopcde == 16 && x == 0 && s == 0)
4372     {
4373       int i;
4374       bu32 az;
4375 
4376       TRACE_INSN (cpu, "A1 = ABS A1 , A0 = ABS A0;");
4377 
4378       az = 0;
4379       for (i = 0; i < 2; ++i)
4380 	{
4381 	  bu32 av;
4382 	  bs40 acc = get_extended_acc (cpu, i);
4383 
4384 	  if (acc >> 39)
4385 	    acc = -acc;
4386 	  av = acc == ((bs40)1 << 39);
4387 	  if (av)
4388 	    acc = ((bs40)1 << 39) - 1;
4389 
4390 	  SET_AREG (i, acc);
4391 	  SET_ASTATREG (av[i], av);
4392 	  if (av)
4393 	    SET_ASTATREG (avs[i], av);
4394 	  az |= (acc == 0);
4395 	}
4396       SET_ASTATREG (az, az);
4397       SET_ASTATREG (an, 0);
4398     }
4399   else if (aop == 0 && aopcde == 23 && x == 0)
4400     {
4401       bu32 s0, s0L, s0H, s1, s1L, s1H;
4402       bs32 tmp0, tmp1;
4403 
4404       TRACE_INSN (cpu, "R%i = BYTEOP3P (R%i:%i, R%i:%i) (%s%s);", dst0,
4405 		  src0 + 1, src0, src1 + 1, src1, HL ? "HI" : "LO",
4406 		  s ? ", R" : "");
4407 
4408       if ((src1 != 0 && src1 != 2) || (src0 != 0 && src0 != 2))
4409 	illegal_instruction (cpu);
4410 
4411       s0L = DREG (src0);
4412       s0H = DREG (src0 + 1);
4413       s1L = DREG (src1);
4414       s1H = DREG (src1 + 1);
4415       if (s)
4416 	{
4417 	  s0 = algn (s0H, s0L, IREG (0) & 3);
4418 	  s1 = algn (s1H, s1L, IREG (1) & 3);
4419 	}
4420       else
4421 	{
4422 	  s0 = algn (s0L, s0H, IREG (0) & 3);
4423 	  s1 = algn (s1L, s1H, IREG (1) & 3);
4424 	}
4425 
4426       tmp0 = (bs32)(bs16)(s0 >>  0) + ((s1 >> ( 0 + (8 * !HL))) & 0xff);
4427       tmp1 = (bs32)(bs16)(s0 >> 16) + ((s1 >> (16 + (8 * !HL))) & 0xff);
4428       STORE (DREG (dst0), (CLAMP (tmp0, 0, 255) << ( 0 + (8 * HL))) |
4429 			  (CLAMP (tmp1, 0, 255) << (16 + (8 * HL))));
4430 
4431       /* Implicit DISALGNEXCPT in parallel.  */
4432       DIS_ALGN_EXPT |= 1;
4433     }
4434   else if ((aop == 0 || aop == 1) && aopcde == 16 && x == 0 && s == 0)
4435     {
4436       bu32 av;
4437       bs40 acc;
4438 
4439       TRACE_INSN (cpu, "A%i = ABS A%i;", HL, aop);
4440 
4441       acc = get_extended_acc (cpu, aop);
4442       if (acc >> 39)
4443 	acc = -acc;
4444       av = acc == ((bs40)1 << 39);
4445       if (av)
4446 	acc = ((bs40)1 << 39) - 1;
4447       SET_AREG (HL, acc);
4448 
4449       SET_ASTATREG (av[HL], av);
4450       if (av)
4451 	SET_ASTATREG (avs[HL], av);
4452       SET_ASTATREG (az, acc == 0);
4453       SET_ASTATREG (an, 0);
4454     }
4455   else if (aop == 3 && aopcde == 12 && x == 0 && s == 0)
4456     {
4457       bs32 res = DREG (src0);
4458       bs32 ovX;
4459       bool sBit_a, sBit_b;
4460 
4461       TRACE_INSN (cpu, "R%i.%s = R%i (RND);", dst0, HL == 0 ? "L" : "H", src0);
4462       TRACE_DECODE (cpu, "R%i.%s = R%i:%#x (RND);", dst0,
4463 		    HL == 0 ? "L" : "H", src0, res);
4464 
4465       sBit_b = !!(res & 0x80000000);
4466 
4467       res += 0x8000;
4468       sBit_a = !!(res & 0x80000000);
4469 
4470       /* Overflow if the sign bit changed when we rounded.  */
4471       if ((res >> 16) && (sBit_b != sBit_a))
4472 	{
4473 	  ovX = 1;
4474 	  if (!sBit_b)
4475 	    res = 0x7FFF;
4476 	  else
4477 	    res = 0x8000;
4478 	}
4479       else
4480 	{
4481 	  res = res >> 16;
4482 	  ovX = 0;
4483 	}
4484 
4485       if (!HL)
4486 	SET_DREG (dst0, REG_H_L (DREG (dst0), res));
4487       else
4488 	SET_DREG (dst0, REG_H_L (res << 16, DREG (dst0)));
4489 
4490       SET_ASTATREG (az, res == 0);
4491       SET_ASTATREG (an, res < 0);
4492       SET_ASTATREG (v, ovX);
4493       if (ovX)
4494 	SET_ASTATREG (vs, ovX);
4495     }
4496   else if (aop == 3 && HL == 0 && aopcde == 15 && x == 0 && s == 0)
4497     {
4498       bu32 hi = (-(bs16)(DREG (src0) >> 16)) << 16;
4499       bu32 lo = (-(bs16)(DREG (src0) & 0xFFFF)) & 0xFFFF;
4500       int v, ac0, ac1;
4501 
4502       TRACE_INSN (cpu, "R%i = -R%i (V);", dst0, src0);
4503 
4504       v = ac0 = ac1 = 0;
4505 
4506       if (hi == 0x80000000)
4507 	{
4508 	  hi = 0x7fff0000;
4509 	  v = 1;
4510 	}
4511       else if (hi == 0)
4512 	ac1 = 1;
4513 
4514       if (lo == 0x8000)
4515 	{
4516 	  lo = 0x7fff;
4517 	  v = 1;
4518 	}
4519       else if (lo == 0)
4520 	ac0 = 1;
4521 
4522       SET_DREG (dst0, hi | lo);
4523 
4524       SET_ASTATREG (v, v);
4525       if (v)
4526 	SET_ASTATREG (vs, 1);
4527       SET_ASTATREG (ac0, ac0);
4528       SET_ASTATREG (ac1, ac1);
4529       setflags_nz_2x16 (cpu, DREG (dst0));
4530     }
4531   else if (aop == 3 && HL == 0 && aopcde == 14 && x == 0 && s == 0)
4532     {
4533       TRACE_INSN (cpu, "A1 = - A1 , A0 = - A0;");
4534 
4535       SET_AREG (0, saturate_s40 (-get_extended_acc (cpu, 0)));
4536       SET_AREG (1, saturate_s40 (-get_extended_acc (cpu, 1)));
4537       /* XXX: what ASTAT flags need updating ?  */
4538     }
4539   else if ((aop == 0 || aop == 1) && aopcde == 14 && x == 0 && s == 0)
4540     {
4541       bs40 src_acc = get_extended_acc (cpu, aop);
4542       bu32 v = 0;
4543 
4544       TRACE_INSN (cpu, "A%i = - A%i;", HL, aop);
4545 
4546       SET_AREG (HL, saturate_s40_astat (-src_acc, &v));
4547 
4548       SET_ASTATREG (az, AWREG (HL) == 0 && AXREG (HL) == 0);
4549       SET_ASTATREG (an, AXREG (HL) >> 7);
4550       if (HL == 0)
4551 	{
4552 	  SET_ASTATREG (ac0, !src_acc);
4553 	  SET_ASTATREG (av0, v);
4554 	  if (v)
4555 	    SET_ASTATREG (av0s, 1);
4556 	}
4557       else
4558 	{
4559 	  SET_ASTATREG (ac1, !src_acc);
4560 	  SET_ASTATREG (av1, v);
4561 	  if (v)
4562 	    SET_ASTATREG (av1s, 1);
4563 	}
4564     }
4565   else if (aop == 0 && aopcde == 12 && x == 0 && s == 0 && HL == 0)
4566     {
4567       bs16 tmp0_hi = DREG (src0) >> 16;
4568       bs16 tmp0_lo = DREG (src0);
4569       bs16 tmp1_hi = DREG (src1) >> 16;
4570       bs16 tmp1_lo = DREG (src1);
4571 
4572       TRACE_INSN (cpu, "R%i.L = R%i.H = SIGN(R%i.H) * R%i.H + SIGN(R%i.L) * R%i.L;",
4573 		  dst0, dst0, src0, src1, src0, src1);
4574 
4575       if ((tmp0_hi >> 15) & 1)
4576 	tmp1_hi = ~tmp1_hi + 1;
4577 
4578       if ((tmp0_lo >> 15) & 1)
4579 	tmp1_lo = ~tmp1_lo + 1;
4580 
4581       tmp1_hi = tmp1_hi + tmp1_lo;
4582 
4583       STORE (DREG (dst0), REG_H_L (tmp1_hi << 16, tmp1_hi));
4584     }
4585   else if (aopcde == 0 && HL == 0)
4586     {
4587       bu32 s0 = DREG (src0);
4588       bu32 s1 = DREG (src1);
4589       bu32 s0h = s0 >> 16;
4590       bu32 s0l = s0 & 0xFFFF;
4591       bu32 s1h = s1 >> 16;
4592       bu32 s1l = s1 & 0xFFFF;
4593       bu32 t0, t1;
4594       bu32 ac1_i = 0, ac0_i = 0, v_i = 0, z_i = 0, n_i = 0;
4595 
4596       TRACE_INSN (cpu, "R%i = R%i %c|%c R%i%s;", dst0, src0,
4597 		  (aop & 2) ? '-' : '+', (aop & 1) ? '-' : '+', src1,
4598 		  amod0 (s, x));
4599       if (aop & 2)
4600 	t0 = sub16 (cpu, s0h, s1h, &ac1_i, &v_i, &z_i, &n_i, s, 0);
4601       else
4602 	t0 = add16 (cpu, s0h, s1h, &ac1_i, &v_i, &z_i, &n_i, s, 0);
4603 
4604       if (aop & 1)
4605 	t1 = sub16 (cpu, s0l, s1l, &ac0_i, &v_i, &z_i, &n_i, s, 0);
4606       else
4607 	t1 = add16 (cpu, s0l, s1l, &ac0_i, &v_i, &z_i, &n_i, s, 0);
4608 
4609       SET_ASTATREG (ac1, ac1_i);
4610       SET_ASTATREG (ac0, ac0_i);
4611       SET_ASTATREG (az, z_i);
4612       SET_ASTATREG (an, n_i);
4613       SET_ASTATREG (v, v_i);
4614       if (v_i)
4615 	SET_ASTATREG (vs, v_i);
4616 
4617       t0 &= 0xFFFF;
4618       t1 &= 0xFFFF;
4619       if (x)
4620 	SET_DREG (dst0, (t1 << 16) | t0);
4621       else
4622 	SET_DREG (dst0, (t0 << 16) | t1);
4623     }
4624   else if (aop == 1 && aopcde == 12 && x == 0 && s == 0 && HL == 0)
4625     {
4626       bs32 val0 = (bs16)(AWREG (0) >> 16) + (bs16)AWREG (0);
4627       bs32 val1 = (bs16)(AWREG (1) >> 16) + (bs16)AWREG (1);
4628 
4629       TRACE_INSN (cpu, "R%i = A1.L + A1.H, R%i = A0.L + A0.H;", dst1, dst0);
4630 
4631       if (dst0 == dst1)
4632 	illegal_instruction_combination (cpu);
4633 
4634       SET_DREG (dst0, val0);
4635       SET_DREG (dst1, val1);
4636     }
4637   else if ((aop == 0 || aop == 2 || aop == 3) && aopcde == 1)
4638     {
4639       bu32 d0, d1;
4640       bu32 x0, x1;
4641       bu16 s0L = DREG (src0);
4642       bu16 s0H = DREG (src0) >> 16;
4643       bu16 s1L = DREG (src1);
4644       bu16 s1H = DREG (src1) >> 16;
4645       bu32 v_i = 0, n_i = 0, z_i = 0;
4646 
4647       TRACE_INSN (cpu, "R%i = R%i %s R%i, R%i = R%i %s R%i%s;",
4648 		  dst1, src0, HL ? "+|-" : "+|+", src1,
4649 		  dst0, src0, HL ? "-|+" : "-|-", src1,
4650 		  amod0amod2 (s, x, aop));
4651 
4652       if (dst0 == dst1)
4653 	illegal_instruction_combination (cpu);
4654 
4655       if (HL == 0)
4656 	{
4657 	  x0 = add16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4658 	  x1 = add16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4659 	  d1 = (x0 << 16) | x1;
4660 
4661 	  x0 = sub16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4662 	  x1 = sub16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4663 	  if (x == 0)
4664 	    d0 = (x0 << 16) | x1;
4665 	  else
4666 	    d0 = (x1 << 16) | x0;
4667 	}
4668       else
4669 	{
4670 	  x0 = add16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4671 	  x1 = sub16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4672 	  d1 = (x0 << 16) | x1;
4673 
4674 	  x0 = sub16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4675 	  x1 = add16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4676 	  if (x == 0)
4677 	    d0 = (x0 << 16) | x1;
4678 	  else
4679 	    d0 = (x1 << 16) | x0;
4680 	}
4681       SET_ASTATREG (az, z_i);
4682       SET_ASTATREG (an, n_i);
4683       SET_ASTATREG (v, v_i);
4684       if (v_i)
4685 	SET_ASTATREG (vs, v_i);
4686 
4687       STORE (DREG (dst0), d0);
4688       STORE (DREG (dst1), d1);
4689     }
4690   else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 11 && x == 0)
4691     {
4692       bs40 acc0 = get_extended_acc (cpu, 0);
4693       bs40 acc1 = get_extended_acc (cpu, 1);
4694       bu32 v, dreg, sat = 0;
4695       bu32 carry = !!((bu40)~acc1 < (bu40)acc0);
4696 
4697       if (aop == 0)
4698 	{
4699 	  if (s != 0 || HL != 0)
4700 	    illegal_instruction (cpu);
4701 	  TRACE_INSN (cpu, "R%i = (A0 += A1);", dst0);
4702 	}
4703       else if (aop == 1)
4704 	{
4705 	  if (s != 0)
4706 	    illegal_instruction (cpu);
4707 	  TRACE_INSN (cpu, "R%i.%c = (A0 += A1);", dst0, HL ? 'H' : 'L');
4708 	}
4709       else
4710 	{
4711 	  if (HL != 0)
4712 	    illegal_instruction (cpu);
4713 	  TRACE_INSN (cpu, "A0 += A1%s;", s ? " (W32)" : "");
4714 	}
4715 
4716       acc0 += acc1;
4717       acc0 = saturate_s40_astat (acc0, &v);
4718 
4719       if (aop == 2 && s == 1)   /* A0 += A1 (W32)  */
4720 	{
4721 	  if (acc0 & (bs40)0x8000000000ll)
4722 	    acc0 &= 0x80ffffffffll;
4723 	  else
4724 	    acc0 &= 0xffffffffll;
4725 	}
4726 
4727       STORE (AXREG (0), acc0 >> 32);
4728       STORE (AWREG (0), acc0);
4729       SET_ASTATREG (av0, v && acc1);
4730       if (v)
4731 	SET_ASTATREG (av0s, v);
4732 
4733       if (aop == 0 || aop == 1)
4734 	{
4735 	  if (aop)	/* Dregs_lo = A0 += A1  */
4736 	    {
4737 	      dreg = saturate_s32 (rnd16 (acc0) << 16, &sat);
4738 	      if (HL)
4739 		STORE (DREG (dst0), REG_H_L (dreg, DREG (dst0)));
4740 	      else
4741 		STORE (DREG (dst0), REG_H_L (DREG (dst0), dreg >> 16));
4742 	    }
4743 	  else		/* Dregs = A0 += A1  */
4744 	    {
4745 	      dreg = saturate_s32 (acc0, &sat);
4746 	      STORE (DREG (dst0), dreg);
4747 	    }
4748 
4749 	  STORE (ASTATREG (az), dreg == 0);
4750 	  STORE (ASTATREG (an), !!(dreg & 0x80000000));
4751 	  STORE (ASTATREG (ac0), carry);
4752 	  STORE (ASTATREG (ac0_copy), carry);
4753 	  STORE (ASTATREG (v), sat);
4754 	  STORE (ASTATREG (v_copy), sat);
4755 	  if (sat)
4756 	    STORE (ASTATREG (vs), sat);
4757 	}
4758       else
4759 	{
4760 	  STORE (ASTATREG (az), acc0 == 0);
4761 	  STORE (ASTATREG (an), !!(acc0 & 0x8000000000ull));
4762 	  STORE (ASTATREG (ac0), carry);
4763 	  STORE (ASTATREG (ac0_copy), carry);
4764 	}
4765     }
4766   else if ((aop == 0 || aop == 1) && aopcde == 10 && x == 0 && s == 0 && HL == 0)
4767     {
4768       TRACE_INSN (cpu, "R%i.L = A%i.X;", dst0, aop);
4769       SET_DREG_L (dst0, (bs8)AXREG (aop));
4770     }
4771   else if (aop == 0 && aopcde == 4 && x == 0 && HL == 0)
4772     {
4773       TRACE_INSN (cpu, "R%i = R%i + R%i%s;", dst0, src0, src1, amod1 (s, x));
4774       SET_DREG (dst0, add32 (cpu, DREG (src0), DREG (src1), 1, s));
4775     }
4776   else if (aop == 1 && aopcde == 4 && x == 0 && HL == 0)
4777     {
4778       TRACE_INSN (cpu, "R%i = R%i - R%i%s;", dst0, src0, src1, amod1 (s, x));
4779       SET_DREG (dst0, sub32 (cpu, DREG (src0), DREG (src1), 1, s, 0));
4780     }
4781   else if (aop == 2 && aopcde == 4 && x == 0 && HL == 0)
4782     {
4783       TRACE_INSN (cpu, "R%i = R%i + R%i, R%i = R%i - R%i%s;",
4784 		  dst1, src0, src1, dst0, src0, src1, amod1 (s, x));
4785 
4786       if (dst0 == dst1)
4787 	illegal_instruction_combination (cpu);
4788 
4789       STORE (DREG (dst1), add32 (cpu, DREG (src0), DREG (src1), 1, s));
4790       STORE (DREG (dst0), sub32 (cpu, DREG (src0), DREG (src1), 1, s, 1));
4791     }
4792   else if ((aop == 0 || aop == 1) && aopcde == 17 && x == 0 && HL == 0)
4793     {
4794       bs40 acc0 = get_extended_acc (cpu, 0);
4795       bs40 acc1 = get_extended_acc (cpu, 1);
4796       bs40 val0, val1, sval0, sval1;
4797       bu32 sat, sat_i;
4798 
4799       TRACE_INSN (cpu, "R%i = A%i + A%i, R%i = A%i - A%i%s",
4800 		  dst1, !aop, aop, dst0, !aop, aop, amod1 (s, x));
4801       TRACE_DECODE (cpu, "R%i = A%i:%#"PRIx64" + A%i:%#"PRIx64", "
4802 			 "R%i = A%i:%#"PRIx64" - A%i:%#"PRIx64"%s",
4803 		    dst1, !aop, aop ? acc0 : acc1, aop, aop ? acc1 : acc0,
4804 		    dst0, !aop, aop ? acc0 : acc1, aop, aop ? acc1 : acc0,
4805 		    amod1 (s, x));
4806 
4807       if (dst0 == dst1)
4808 	illegal_instruction_combination (cpu);
4809 
4810       val1 = acc0 + acc1;
4811       if (aop)
4812 	val0 = acc0 - acc1;
4813       else
4814 	val0 = acc1 - acc0;
4815 
4816       sval0 = saturate_s32 (val0, &sat);
4817       sat_i = sat;
4818       sval1 = saturate_s32 (val1, &sat);
4819       sat_i |= sat;
4820       if (s)
4821 	{
4822 	  val0 = sval0;
4823 	  val1 = sval1;
4824 	}
4825 
4826       STORE (DREG (dst0), val0);
4827       STORE (DREG (dst1), val1);
4828       SET_ASTATREG (v, sat_i);
4829       if (sat_i)
4830 	SET_ASTATREG (vs, sat_i);
4831       SET_ASTATREG (an, val0 & 0x80000000 || val1 & 0x80000000);
4832       SET_ASTATREG (az, val0 == 0 || val1 == 0);
4833       SET_ASTATREG (ac1, (bu40)~acc0 < (bu40)acc1);
4834       if (aop)
4835 	SET_ASTATREG (ac0, !!((bu40)acc1 <= (bu40)acc0));
4836       else
4837 	SET_ASTATREG (ac0, !!((bu40)acc0 <= (bu40)acc1));
4838     }
4839   else if (aop == 0 && aopcde == 18 && x == 0 && HL == 0)
4840     {
4841       bu40 acc0 = get_extended_acc (cpu, 0);
4842       bu40 acc1 = get_extended_acc (cpu, 1);
4843       bu32 s0L = DREG (src0);
4844       bu32 s0H = DREG (src0 + 1);
4845       bu32 s1L = DREG (src1);
4846       bu32 s1H = DREG (src1 + 1);
4847       bu32 s0, s1;
4848       bs16 tmp0, tmp1, tmp2, tmp3;
4849 
4850       /* This instruction is only defined for register pairs R1:0 and R3:2.  */
4851       if (!((src0 == 0 || src0 == 2) && (src1 == 0 || src1 == 2)))
4852 	illegal_instruction (cpu);
4853 
4854       TRACE_INSN (cpu, "SAA (R%i:%i, R%i:%i)%s", src0 + 1, src0,
4855 		  src1 + 1, src1, s ? " (R)" :"");
4856 
4857       /* Bit s determines the order of the two registers from a pair:
4858          if s=0 the low-order bytes come from the low reg in the pair,
4859          and if s=1 the low-order bytes come from the high reg.  */
4860 
4861       if (s)
4862 	{
4863 	  s0 = algn (s0H, s0L, IREG (0) & 3);
4864 	  s1 = algn (s1H, s1L, IREG (1) & 3);
4865 	}
4866       else
4867 	{
4868 	  s0 = algn (s0L, s0H, IREG (0) & 3);
4869 	  s1 = algn (s1L, s1H, IREG (1) & 3);
4870 	}
4871 
4872       /* Find the absolute difference between pairs, make it
4873          absolute, then add it to the existing accumulator half.  */
4874       /* Byte 0  */
4875       tmp0  = ((s0 << 24) >> 24) - ((s1 << 24) >> 24);
4876       tmp1  = ((s0 << 16) >> 24) - ((s1 << 16) >> 24);
4877       tmp2  = ((s0 <<  8) >> 24) - ((s1 <<  8) >> 24);
4878       tmp3  = ((s0 <<  0) >> 24) - ((s1 <<  0) >> 24);
4879 
4880       tmp0  = (tmp0 < 0) ? -tmp0 : tmp0;
4881       tmp1  = (tmp1 < 0) ? -tmp1 : tmp1;
4882       tmp2  = (tmp2 < 0) ? -tmp2 : tmp2;
4883       tmp3  = (tmp3 < 0) ? -tmp3 : tmp3;
4884 
4885       s0L = saturate_u16 ((bu32)tmp0 + ((acc0 >>  0) & 0xffff), 0);
4886       s0H = saturate_u16 ((bu32)tmp1 + ((acc0 >> 16) & 0xffff), 0);
4887       s1L = saturate_u16 ((bu32)tmp2 + ((acc1 >>  0) & 0xffff), 0);
4888       s1H = saturate_u16 ((bu32)tmp3 + ((acc1 >> 16) & 0xffff), 0);
4889 
4890       STORE (AWREG (0), (s0H << 16) | (s0L & 0xFFFF));
4891       STORE (AXREG (0), 0);
4892       STORE (AWREG (1), (s1H << 16) | (s1L & 0xFFFF));
4893       STORE (AXREG (1), 0);
4894 
4895       /* Implicit DISALGNEXCPT in parallel.  */
4896       DIS_ALGN_EXPT |= 1;
4897     }
4898   else if (aop == 3 && aopcde == 18 && x == 0 && s == 0 && HL == 0)
4899     {
4900       TRACE_INSN (cpu, "DISALGNEXCPT");
4901       DIS_ALGN_EXPT |= 1;
4902     }
4903   else if ((aop == 0 || aop == 1) && aopcde == 20 && x == 0 && HL == 0)
4904     {
4905       bu32 s0, s0L, s0H, s1, s1L, s1H;
4906       const char * const opts[] = { "", " (R)", " (T)", " (T, R)" };
4907 
4908       TRACE_INSN (cpu, "R%i = BYTEOP1P (R%i:%i, R%i:%i)%s;", dst0,
4909 		  src0 + 1, src0, src1 + 1, src1, opts[s + (aop << 1)]);
4910 
4911       if ((src1 != 0 && src1 != 2) || (src0 != 0 && src0 != 2))
4912 	illegal_instruction (cpu);
4913 
4914       s0L = DREG (src0);
4915       s0H = DREG (src0 + 1);
4916       s1L = DREG (src1);
4917       s1H = DREG (src1 + 1);
4918       if (s)
4919 	{
4920 	  s0 = algn (s0H, s0L, IREG (0) & 3);
4921 	  s1 = algn (s1H, s1L, IREG (1) & 3);
4922 	}
4923       else
4924 	{
4925 	  s0 = algn (s0L, s0H, IREG (0) & 3);
4926 	  s1 = algn (s1L, s1H, IREG (1) & 3);
4927 	}
4928 
4929       STORE (DREG (dst0),
4930 		(((((s0 >>  0) & 0xff) + ((s1 >>  0) & 0xff) + !aop) >> 1) <<  0) |
4931 		(((((s0 >>  8) & 0xff) + ((s1 >>  8) & 0xff) + !aop) >> 1) <<  8) |
4932 		(((((s0 >> 16) & 0xff) + ((s1 >> 16) & 0xff) + !aop) >> 1) << 16) |
4933 		(((((s0 >> 24) & 0xff) + ((s1 >> 24) & 0xff) + !aop) >> 1) << 24));
4934 
4935       /* Implicit DISALGNEXCPT in parallel.  */
4936       DIS_ALGN_EXPT |= 1;
4937     }
4938   else if (aop == 0 && aopcde == 21 && x == 0 && HL == 0)
4939     {
4940       bu32 s0, s0L, s0H, s1, s1L, s1H;
4941 
4942       TRACE_INSN (cpu, "(R%i, R%i) = BYTEOP16P (R%i:%i, R%i:%i)%s;", dst1, dst0,
4943 		  src0 + 1, src0, src1 + 1, src1, s ? " (R)" : "");
4944 
4945       if ((src1 != 0 && src1 != 2) || (src0 != 0 && src0 != 2))
4946 	illegal_instruction (cpu);
4947 
4948       if (dst0 == dst1)
4949 	illegal_instruction_combination (cpu);
4950 
4951       s0L = DREG (src0);
4952       s0H = DREG (src0 + 1);
4953       s1L = DREG (src1);
4954       s1H = DREG (src1 + 1);
4955       if (s)
4956 	{
4957 	  s0 = algn (s0H, s0L, IREG (0) & 3);
4958 	  s1 = algn (s1H, s1L, IREG (1) & 3);
4959 	}
4960       else
4961 	{
4962 	  s0 = algn (s0L, s0H, IREG (0) & 3);
4963 	  s1 = algn (s1L, s1H, IREG (1) & 3);
4964 	}
4965 
4966       STORE (DREG (dst0),
4967 		((((s0 >>  0) & 0xff) + ((s1 >>  0) & 0xff)) <<  0) |
4968 		((((s0 >>  8) & 0xff) + ((s1 >>  8) & 0xff)) << 16));
4969       STORE (DREG (dst1),
4970 		((((s0 >> 16) & 0xff) + ((s1 >> 16) & 0xff)) <<  0) |
4971 		((((s0 >> 24) & 0xff) + ((s1 >> 24) & 0xff)) << 16));
4972 
4973       /* Implicit DISALGNEXCPT in parallel.  */
4974       DIS_ALGN_EXPT |= 1;
4975     }
4976   else if (aop == 1 && aopcde == 21 && x == 0 && HL == 0)
4977     {
4978       bu32 s0, s0L, s0H, s1, s1L, s1H;
4979 
4980       TRACE_INSN (cpu, "(R%i, R%i) = BYTEOP16M (R%i:%i, R%i:%i)%s;", dst1, dst0,
4981 		  src0 + 1, src0, src1 + 1, src1, s ? " (R)" : "");
4982 
4983       if ((src1 != 0 && src1 != 2) || (src0 != 0 && src0 != 2))
4984 	illegal_instruction (cpu);
4985 
4986       if (dst0 == dst1)
4987 	illegal_instruction_combination (cpu);
4988 
4989       s0L = DREG (src0);
4990       s0H = DREG (src0 + 1);
4991       s1L = DREG (src1);
4992       s1H = DREG (src1 + 1);
4993       if (s)
4994 	{
4995 	  s0 = algn (s0H, s0L, IREG (0) & 3);
4996 	  s1 = algn (s1H, s1L, IREG (1) & 3);
4997 	}
4998       else
4999 	{
5000 	  s0 = algn (s0L, s0H, IREG (0) & 3);
5001 	  s1 = algn (s1L, s1H, IREG (1) & 3);
5002 	}
5003 
5004       STORE (DREG (dst0),
5005 		(((((s0 >>  0) & 0xff) - ((s1 >>  0) & 0xff)) <<  0) & 0xffff) |
5006 		(((((s0 >>  8) & 0xff) - ((s1 >>  8) & 0xff)) << 16)));
5007       STORE (DREG (dst1),
5008 		(((((s0 >> 16) & 0xff) - ((s1 >> 16) & 0xff)) <<  0) & 0xffff) |
5009 		(((((s0 >> 24) & 0xff) - ((s1 >> 24) & 0xff)) << 16)));
5010 
5011       /* Implicit DISALGNEXCPT in parallel.  */
5012       DIS_ALGN_EXPT |= 1;
5013     }
5014   else if (aop == 1 && aopcde == 7 && x == 0 && s == 0 && HL == 0)
5015     {
5016       TRACE_INSN (cpu, "R%i = MIN (R%i, R%i);", dst0, src0, src1);
5017       SET_DREG (dst0, min32 (cpu, DREG (src0), DREG (src1)));
5018     }
5019   else if (aop == 0 && aopcde == 7 && x == 0 && s == 0 && HL == 0)
5020     {
5021       TRACE_INSN (cpu, "R%i = MAX (R%i, R%i);", dst0, src0, src1);
5022       SET_DREG (dst0, max32 (cpu, DREG (src0), DREG (src1)));
5023     }
5024   else if (aop == 2 && aopcde == 7 && x == 0 && s == 0 && HL == 0)
5025     {
5026       bu32 val = DREG (src0);
5027       int v;
5028 
5029       TRACE_INSN (cpu, "R%i = ABS R%i;", dst0, src0);
5030 
5031       if (val >> 31)
5032 	val = -val;
5033       v = (val == 0x80000000);
5034       if (v)
5035 	val = 0x7fffffff;
5036       SET_DREG (dst0, val);
5037 
5038       SET_ASTATREG (v, v);
5039       if (v)
5040 	SET_ASTATREG (vs, 1);
5041       setflags_nz (cpu, val);
5042     }
5043   else if (aop == 3 && aopcde == 7 && x == 0 && HL == 0)
5044     {
5045       bu32 val = DREG (src0);
5046 
5047       TRACE_INSN (cpu, "R%i = - R%i%s;", dst0, src0, amod1 (s, 0));
5048 
5049       if (s && val == 0x80000000)
5050 	{
5051 	  val = 0x7fffffff;
5052 	  SET_ASTATREG (v, 1);
5053 	  SET_ASTATREG (vs, 1);
5054 	}
5055       else if (val == 0x80000000)
5056 	val = 0x80000000;
5057       else
5058 	val = -val;
5059       SET_DREG (dst0, val);
5060 
5061       SET_ASTATREG (az, val == 0);
5062       SET_ASTATREG (an, val & 0x80000000);
5063     }
5064   else if (aop == 2 && aopcde == 6 && x == 0 && s == 0 && HL == 0)
5065     {
5066       bu32 in = DREG (src0);
5067       bu32 hi = (in & 0x80000000 ? (bu32)-(bs16)(in >> 16) : in >> 16) << 16;
5068       bu32 lo = (in & 0x8000 ? (bu32)-(bs16)(in & 0xFFFF) : in) & 0xFFFF;
5069       int v;
5070 
5071       TRACE_INSN (cpu, "R%i = ABS R%i (V);", dst0, src0);
5072 
5073       v = 0;
5074       if (hi == 0x80000000)
5075 	{
5076 	  hi = 0x7fff0000;
5077 	  v = 1;
5078 	}
5079       if (lo == 0x8000)
5080 	{
5081 	  lo = 0x7fff;
5082 	  v = 1;
5083 	}
5084       SET_DREG (dst0, hi | lo);
5085 
5086       SET_ASTATREG (v, v);
5087       if (v)
5088 	SET_ASTATREG (vs, 1);
5089       setflags_nz_2x16 (cpu, DREG (dst0));
5090     }
5091   else if (aop == 1 && aopcde == 6 && x == 0 && s == 0 && HL == 0)
5092     {
5093       TRACE_INSN (cpu, "R%i = MIN (R%i, R%i) (V);", dst0, src0, src1);
5094       SET_DREG (dst0, min2x16 (cpu, DREG (src0), DREG (src1)));
5095     }
5096   else if (aop == 0 && aopcde == 6 && x == 0 && s == 0 && HL == 0)
5097     {
5098       TRACE_INSN (cpu, "R%i = MAX (R%i, R%i) (V);", dst0, src0, src1);
5099       SET_DREG (dst0, max2x16 (cpu, DREG (src0), DREG (src1)));
5100     }
5101   else if (aop == 0 && aopcde == 24 && x == 0 && s == 0 && HL == 0)
5102     {
5103       TRACE_INSN (cpu, "R%i = BYTEPACK (R%i, R%i);", dst0, src0, src1);
5104       STORE (DREG (dst0),
5105 	(((DREG (src0) >>  0) & 0xff) <<  0) |
5106 	(((DREG (src0) >> 16) & 0xff) <<  8) |
5107 	(((DREG (src1) >>  0) & 0xff) << 16) |
5108 	(((DREG (src1) >> 16) & 0xff) << 24));
5109 
5110       /* Implicit DISALGNEXCPT in parallel.  */
5111       DIS_ALGN_EXPT |= 1;
5112     }
5113   else if (aop == 1 && aopcde == 24 && x == 0 && HL == 0)
5114     {
5115       int order, lo, hi;
5116       bu64 comb_src;
5117       bu8 bytea, byteb, bytec, byted;
5118 
5119       TRACE_INSN (cpu, "(R%i, R%i) = BYTEUNPACK R%i:%i%s;",
5120 		  dst1, dst0, src0 + 1, src0, s ? " (R)" : "");
5121 
5122       if ((src1 != 0 && src1 != 2) || (src0 != 0 && src0 != 2))
5123 	illegal_instruction (cpu);
5124 
5125       if (dst0 == dst1)
5126 	illegal_instruction_combination (cpu);
5127 
5128       order = IREG (0) & 0x3;
5129       if (s)
5130 	hi = src0, lo = src0 + 1;
5131       else
5132 	hi = src0 + 1, lo = src0;
5133       comb_src = (((bu64)DREG (hi)) << 32) | DREG (lo);
5134       bytea = (comb_src >> (0 + 8 * order));
5135       byteb = (comb_src >> (8 + 8 * order));
5136       bytec = (comb_src >> (16 + 8 * order));
5137       byted = (comb_src >> (24 + 8 * order));
5138       STORE (DREG (dst0), bytea | ((bu32)byteb << 16));
5139       STORE (DREG (dst1), bytec | ((bu32)byted << 16));
5140 
5141       /* Implicit DISALGNEXCPT in parallel.  */
5142       DIS_ALGN_EXPT |= 1;
5143     }
5144   else if (aopcde == 13 && HL == 0 && x == 0 && s == 0)
5145     {
5146       const char *searchmodes[] = { "GT", "GE", "LT", "LE" };
5147       bool up_hi, up_lo;
5148       bs16 a0_lo, a1_lo, src_hi, src_lo;
5149 
5150       TRACE_INSN (cpu, "(R%i, R%i) = SEARCH R%i (%s);",
5151 		  dst1, dst0, src0, searchmodes[aop]);
5152 
5153       /* XXX: The parallel version is a bit weird in its limits:
5154 
5155          This instruction can be issued in parallel with the combination of one
5156          16-bit length load instruction to the P0 register and one 16-bit NOP.
5157          No other instructions can be issued in parallel with the Vector Search
5158          instruction. Note the following legal and illegal forms.
5159          (r1, r0) = search r2 (LT) || r2 = [p0++p3]; // ILLEGAL
5160          (r1, r0) = search r2 (LT) || r2 = [p0++];   // LEGAL
5161          (r1, r0) = search r2 (LT) || r2 = [p0++];   // LEGAL
5162 
5163          Unfortunately, our parallel insn state doesn't (currently) track enough
5164          details to be able to check this.  */
5165 
5166       if (dst0 == dst1)
5167 	illegal_instruction_combination (cpu);
5168 
5169       up_hi = up_lo = false;
5170       a0_lo = AWREG (0);
5171       a1_lo = AWREG (1);
5172       src_lo = DREG (src0);
5173       src_hi = DREG (src0) >> 16;
5174 
5175       switch (aop)
5176 	{
5177 	case 0:
5178 	  up_hi = (src_hi > a1_lo);
5179 	  up_lo = (src_lo > a0_lo);
5180 	  break;
5181 	case 1:
5182 	  up_hi = (src_hi >= a1_lo);
5183 	  up_lo = (src_lo >= a0_lo);
5184 	  break;
5185 	case 2:
5186 	  up_hi = (src_hi < a1_lo);
5187 	  up_lo = (src_lo < a0_lo);
5188 	  break;
5189 	case 3:
5190 	  up_hi = (src_hi <= a1_lo);
5191 	  up_lo = (src_lo <= a0_lo);
5192 	  break;
5193 	}
5194 
5195       if (up_hi)
5196 	{
5197 	  SET_AREG (1, src_hi);
5198 	  SET_DREG (dst1, PREG (0));
5199 	}
5200       else
5201 	SET_AREG (1, a1_lo);
5202 
5203       if (up_lo)
5204 	{
5205 	  SET_AREG (0, src_lo);
5206 	  SET_DREG (dst0, PREG (0));
5207 	}
5208       else
5209 	SET_AREG (0, a0_lo);
5210     }
5211   else
5212     illegal_instruction (cpu);
5213 }
5214 
5215 static void
5216 decode_dsp32shift_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
5217 {
5218   /* dsp32shift
5219      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
5220      | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
5221      |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
5222      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
5223   int HLs  = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
5224   int sop  = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
5225   int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
5226   int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
5227   int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
5228   int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
5229   int M = ((iw0 >> (DSP32Shift_M_bits - 16)) & DSP32Shift_M_mask);
5230 
5231   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32shift);
5232   TRACE_EXTRACT (cpu, "%s: M:%i sopcde:%i sop:%i HLs:%i dst0:%i src0:%i src1:%i",
5233 		 __func__, M, sopcde, sop, HLs, dst0, src0, src1);
5234 
5235   if ((sop == 0 || sop == 1) && sopcde == 0)
5236     {
5237       bu16 val;
5238       bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5239 
5240       TRACE_INSN (cpu, "R%i.%c = ASHIFT R%i.%c BY R%i.L%s;",
5241 		  dst0, HLs < 2 ? 'L' : 'H',
5242 		  src1, HLs & 1 ? 'H' : 'L',
5243 		  src0, sop == 1 ? " (S)" : "");
5244 
5245       if ((HLs & 1) == 0)
5246 	val = (bu16)(DREG (src1) & 0xFFFF);
5247       else
5248 	val = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
5249 
5250       /* Positive shift magnitudes produce Logical Left shifts.
5251          Negative shift magnitudes produce Arithmetic Right shifts.  */
5252       if (shft <= 0)
5253 	val = ashiftrt (cpu, val, -shft, 16);
5254       else
5255 	{
5256 	  int sgn = (val >> 15) & 0x1;
5257 
5258 	  val = lshift (cpu, val, shft, 16, sop == 1, 1);
5259 	  if (((val >> 15) & 0x1) != sgn)
5260 	    {
5261 	      SET_ASTATREG (v, 1);
5262 	      SET_ASTATREG (vs, 1);
5263 	    }
5264 	}
5265 
5266       if ((HLs & 2) == 0)
5267 	STORE (DREG (dst0), REG_H_L (DREG (dst0), val));
5268       else
5269 	STORE (DREG (dst0), REG_H_L (val << 16, DREG (dst0)));
5270     }
5271   else if (sop == 2 && sopcde == 0)
5272     {
5273       bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5274       bu16 val;
5275 
5276       TRACE_INSN (cpu, "R%i.%c = LSHIFT R%i.%c BY R%i.L;",
5277 		  dst0, HLs < 2 ? 'L' : 'H',
5278 		  src1, HLs & 1 ? 'H' : 'L', src0);
5279 
5280       if ((HLs & 1) == 0)
5281 	val = (bu16)(DREG (src1) & 0xFFFF);
5282       else
5283 	val = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
5284 
5285       if (shft < 0)
5286 	val = val >> (-1 * shft);
5287       else
5288 	val = val << shft;
5289 
5290       if ((HLs & 2) == 0)
5291 	SET_DREG (dst0, REG_H_L (DREG (dst0), val));
5292       else
5293 	SET_DREG (dst0, REG_H_L (val << 16, DREG (dst0)));
5294 
5295       SET_ASTATREG (az, !((val & 0xFFFF0000) == 0) || ((val & 0xFFFF) == 0));
5296       SET_ASTATREG (an, (!!(val & 0x80000000)) ^ (!!(val & 0x8000)));
5297       SET_ASTATREG (v, 0);
5298     }
5299   else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0))
5300     {
5301       int shift = imm6 (DREG (src0) & 0xFFFF);
5302       bu32 cc = CCREG;
5303       bu40 acc = get_unextended_acc (cpu, HLs);
5304 
5305       TRACE_INSN (cpu, "A%i = ROT A%i BY R%i.L;", HLs, HLs, src0);
5306       TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc);
5307 
5308       acc = rot40 (acc, shift, &cc);
5309       SET_AREG (HLs, acc);
5310       if (shift)
5311 	SET_CCREG (cc);
5312     }
5313   else if (sop == 0 && sopcde == 3 && (HLs == 0 || HLs == 1))
5314     {
5315       bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5316       bu64 acc = get_extended_acc (cpu, HLs);
5317       bu64 val;
5318 
5319       HLs = !!HLs;
5320       TRACE_INSN (cpu, "A%i = ASHIFT A%i BY R%i.L;", HLs, HLs, src0);
5321       TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, acc, shft);
5322 
5323       if (shft <= 0)
5324 	val = ashiftrt (cpu, acc, -shft, 40);
5325       else
5326 	val = lshift (cpu, acc, shft, 40, 0, 0);
5327 
5328       STORE (AXREG (HLs), (val >> 32) & 0xff);
5329       STORE (AWREG (HLs), (val & 0xffffffff));
5330       STORE (ASTATREG (av[HLs]), 0);
5331     }
5332   else if (sop == 1 && sopcde == 3 && (HLs == 0 || HLs == 1))
5333     {
5334       bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5335       bu64 acc = get_unextended_acc (cpu, HLs);
5336       bu64 val;
5337 
5338       HLs = !!HLs;
5339       TRACE_INSN (cpu, "A%i = LSHIFT A%i BY R%i.L;", HLs, HLs, src0);
5340       TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, acc, shft);
5341 
5342       if (shft <= 0)
5343 	val = lshiftrt (cpu, acc, -shft, 40);
5344       else
5345 	val = lshift (cpu, acc, shft, 40, 0, 0);
5346 
5347       STORE (AXREG (HLs), (val >> 32) & 0xff);
5348       STORE (AWREG (HLs), (val & 0xffffffff));
5349       STORE (ASTATREG (av[HLs]), 0);
5350     }
5351   else if (HLs != 0)
5352     /* All the insns after this point don't use HLs.  */
5353     illegal_instruction (cpu);
5354   else if ((sop == 0 || sop == 1) && sopcde == 1 && HLs == 0)
5355     {
5356       bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5357       bu16 val0, val1;
5358       bu32 astat;
5359 
5360       TRACE_INSN (cpu, "R%i = ASHIFT R%i BY R%i.L (V%s);",
5361 		  dst0, src1, src0, sop == 1 ? ",S" : "");
5362 
5363       val0 = (bu16)DREG (src1) & 0xFFFF;
5364       val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
5365 
5366       if (shft <= 0)
5367 	{
5368 	  val0 = ashiftrt (cpu, val0, -shft, 16);
5369 	  astat = ASTAT;
5370 	  val1 = ashiftrt (cpu, val1, -shft, 16);
5371 	}
5372       else
5373 	{
5374 	  int sgn0 = (val0 >> 15) & 0x1;
5375 	  int sgn1 = (val1 >> 15) & 0x1;
5376 
5377 	  val0 = lshift (cpu, val0, shft, 16, sop == 1, 1);
5378 	  astat = ASTAT;
5379 	  val1 = lshift (cpu, val1, shft, 16, sop == 1, 1);
5380 
5381 	  if ((sgn0 != ((val0 >> 15) & 0x1)) || (sgn1 != ((val1 >> 15) & 0x1)))
5382 	    {
5383 	      SET_ASTATREG (v, 1);
5384 	      SET_ASTATREG (vs, 1);
5385 	    }
5386 	}
5387       SET_ASTAT (ASTAT | astat);
5388       STORE (DREG (dst0), (val1 << 16) | val0);
5389     }
5390   else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 2)
5391     {
5392       /* dregs = [LA]SHIFT dregs BY dregs_lo (opt_S)  */
5393       /* sop == 1 : opt_S  */
5394       bu32 v = DREG (src1);
5395       /* LSHIFT uses sign extended low 6 bits of dregs_lo.  */
5396       bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5397 
5398       TRACE_INSN (cpu, "R%i = %cSHIFT R%i BY R%i.L%s;", dst0,
5399 		  shft && sop != 2 ? 'A' : 'L', src1, src0,
5400 		  sop == 1 ? " (S)" : "");
5401 
5402       if (shft < 0)
5403 	{
5404 	  if (sop == 2)
5405 	    STORE (DREG (dst0), lshiftrt (cpu, v, -shft, 32));
5406 	  else
5407 	    STORE (DREG (dst0), ashiftrt (cpu, v, -shft, 32));
5408 	}
5409       else
5410 	{
5411 	  bu32 val = lshift (cpu, v, shft, 32, sop == 1, 1);
5412 
5413 	  STORE (DREG (dst0), val);
5414 	  if (((v >> 31) & 0x1) != ((val >> 31) & 0x1))
5415 	    {
5416 	      SET_ASTATREG (v, 1);
5417 	      SET_ASTATREG (vs, 1);
5418 	    }
5419 	}
5420     }
5421   else if (sop == 3 && sopcde == 2)
5422     {
5423       int shift = imm6 (DREG (src0) & 0xFFFF);
5424       bu32 src = DREG (src1);
5425       bu32 ret, cc = CCREG;
5426 
5427       TRACE_INSN (cpu, "R%i = ROT R%i BY R%i.L;", dst0, src1, src0);
5428       TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i",
5429 		    dst0, DREG (dst0), src1, src, shift, cc);
5430 
5431       ret = rot32 (src, shift, &cc);
5432       STORE (DREG (dst0), ret);
5433       if (shift)
5434 	SET_CCREG (cc);
5435     }
5436   else if (sop == 2 && sopcde == 1 && HLs == 0)
5437     {
5438       bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5439       bu16 val0, val1;
5440       bu32 astat;
5441 
5442       TRACE_INSN (cpu, "R%i = LSHIFT R%i BY R%i.L (V);", dst0, src1, src0);
5443 
5444       val0 = (bu16)DREG (src1) & 0xFFFF;
5445       val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
5446 
5447       if (shft <= 0)
5448 	{
5449 	  val0 = lshiftrt (cpu, val0, -shft, 16);
5450 	  astat = ASTAT;
5451 	  val1 = lshiftrt (cpu, val1, -shft, 16);
5452 	}
5453       else
5454 	{
5455 	  val0 = lshift (cpu, val0, shft, 16, 0, 0);
5456 	  astat = ASTAT;
5457 	  val1 = lshift (cpu, val1, shft, 16, 0, 0);
5458 	}
5459       SET_ASTAT (ASTAT | astat);
5460       STORE (DREG (dst0), (val1 << 16) | val0);
5461     }
5462   else if (sopcde == 4)
5463     {
5464       bu32 sv0 = DREG (src0);
5465       bu32 sv1 = DREG (src1);
5466       TRACE_INSN (cpu, "R%i = PACK (R%i.%c, R%i.%c);", dst0,
5467 		  src1, sop & 2 ? 'H' : 'L',
5468 		  src0, sop & 1 ? 'H' : 'L');
5469       if (sop & 1)
5470 	sv0 >>= 16;
5471       if (sop & 2)
5472 	sv1 >>= 16;
5473       STORE (DREG (dst0), (sv1 << 16) | (sv0 & 0xFFFF));
5474     }
5475   else if (sop == 0 && sopcde == 5)
5476     {
5477       bu32 sv1 = DREG (src1);
5478       TRACE_INSN (cpu, "R%i.L = SIGNBITS R%i;", dst0, src1);
5479       SET_DREG_L (dst0, signbits (sv1, 32));
5480     }
5481   else if (sop == 1 && sopcde == 5)
5482     {
5483       bu32 sv1 = DREG (src1);
5484       TRACE_INSN (cpu, "R%i.L = SIGNBITS R%i.L;", dst0, src1);
5485       SET_DREG_L (dst0, signbits (sv1, 16));
5486     }
5487   else if (sop == 2 && sopcde == 5)
5488     {
5489       bu32 sv1 = DREG (src1);
5490       TRACE_INSN (cpu, "R%i.L = SIGNBITS R%i.H;", dst0, src1);
5491       SET_DREG_L (dst0, signbits (sv1 >> 16, 16));
5492     }
5493   else if ((sop == 0 || sop == 1) && sopcde == 6)
5494     {
5495       bu64 acc = AXREG (sop);
5496       TRACE_INSN (cpu, "R%i.L = SIGNBITS A%i;", dst0, sop);
5497       acc <<= 32;
5498       acc |= AWREG (sop);
5499       SET_DREG_L (dst0, signbits (acc, 40) & 0xFFFF);
5500     }
5501   else if (sop == 3 && sopcde == 6)
5502     {
5503       bu32 v = ones (DREG (src1));
5504       TRACE_INSN (cpu, "R%i.L = ONES R%i;", dst0, src1);
5505       SET_DREG_L (dst0, v);
5506     }
5507   else if (sop == 0 && sopcde == 7)
5508     {
5509       bu16 sv1 = (bu16)signbits (DREG (src1), 32);
5510       bu16 sv0 = (bu16)DREG (src0);
5511       bu16 dst_lo;
5512 
5513       TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i, R%i.L);", dst0, src1, src0);
5514 
5515       if ((sv1 & 0x1f) < (sv0 & 0x1f))
5516 	dst_lo = sv1;
5517       else
5518 	dst_lo = sv0;
5519       STORE (DREG (dst0), REG_H_L (DREG (dst0), dst_lo));
5520     }
5521   else if (sop == 1 && sopcde == 7)
5522     {
5523       /* Exponent adjust on two 16-bit inputs.  Select
5524          smallest norm among 3 inputs.  */
5525       bs16 src1_hi = (DREG (src1) & 0xFFFF0000) >> 16;
5526       bs16 src1_lo = (DREG (src1) & 0xFFFF);
5527       bu16 src0_lo = (DREG (src0) & 0xFFFF);
5528       bu16 tmp_hi, tmp_lo, tmp;
5529 
5530       TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i, R%i.L) (V);", dst0, src1, src0);
5531 
5532       tmp_hi = signbits (src1_hi, 16);
5533       tmp_lo = signbits (src1_lo, 16);
5534 
5535       if ((tmp_hi & 0xf) < (tmp_lo & 0xf))
5536 	if ((tmp_hi & 0xf) < (src0_lo & 0xf))
5537 	  tmp = tmp_hi;
5538 	else
5539 	  tmp = src0_lo;
5540       else
5541 	if ((tmp_lo & 0xf) < (src0_lo & 0xf))
5542 	  tmp = tmp_lo;
5543 	else
5544 	  tmp = src0_lo;
5545       STORE (DREG (dst0), REG_H_L (DREG (dst0), tmp));
5546     }
5547   else if (sop == 2 && sopcde == 7)
5548     {
5549       /* Exponent adjust on single 16-bit register.  */
5550       bu16 tmp;
5551       bu16 src0_lo = (bu16)(DREG (src0) & 0xFFFF);
5552 
5553       TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i.L, R%i.L);", dst0, src1, src0);
5554 
5555       tmp = signbits (DREG (src1) & 0xFFFF, 16);
5556 
5557       if ((tmp & 0xf) < (src0_lo & 0xf))
5558 	SET_DREG_L (dst0, tmp);
5559       else
5560 	SET_DREG_L (dst0, src0_lo);
5561     }
5562   else if (sop == 3 && sopcde == 7)
5563     {
5564       bu16 tmp;
5565       bu16 src0_lo = (bu16)(DREG (src0) & 0xFFFF);
5566 
5567       TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i.H, R%i.L);", dst0, src1, src0);
5568 
5569       tmp = signbits ((DREG (src1) & 0xFFFF0000) >> 16, 16);
5570 
5571       if ((tmp & 0xf) < (src0_lo & 0xf))
5572 	SET_DREG_L (dst0, tmp);
5573       else
5574 	SET_DREG_L (dst0, src0_lo);
5575     }
5576   else if (sop == 0 && sopcde == 8)
5577     {
5578       bu64 acc = get_unextended_acc (cpu, 0);
5579       bu32 s0, s1;
5580 
5581       TRACE_INSN (cpu, "BITMUX (R%i, R%i, A0) (ASR);", src0, src1);
5582 
5583       if (src0 == src1)
5584 	illegal_instruction_combination (cpu);
5585 
5586       s0 = DREG (src0);
5587       s1 = DREG (src1);
5588       acc = (acc >> 2) |
5589 	(((bu64)s0 & 1) << 38) |
5590 	(((bu64)s1 & 1) << 39);
5591       STORE (DREG (src0), s0 >> 1);
5592       STORE (DREG (src1), s1 >> 1);
5593 
5594       SET_AREG (0, acc);
5595     }
5596   else if (sop == 1 && sopcde == 8)
5597     {
5598       bu64 acc = get_unextended_acc (cpu, 0);
5599       bu32 s0, s1;
5600 
5601       TRACE_INSN (cpu, "BITMUX (R%i, R%i, A0) (ASL);", src0, src1);
5602 
5603       if (src0 == src1)
5604 	illegal_instruction_combination (cpu);
5605 
5606       s0 = DREG (src0);
5607       s1 = DREG (src1);
5608       acc = (acc << 2) |
5609 	((s0 >> 31) & 1) |
5610 	((s1 >> 30) & 2);
5611       STORE (DREG (src0), s0 << 1);
5612       STORE (DREG (src1), s1 << 1);
5613 
5614       SET_AREG (0, acc);
5615     }
5616   else if ((sop == 0 || sop == 1) && sopcde == 9)
5617     {
5618       bs40 acc0 = get_unextended_acc (cpu, 0);
5619       bs16 sL, sH, out;
5620 
5621       TRACE_INSN (cpu, "R%i.L = VIT_MAX (R%i) (AS%c);",
5622 		  dst0, src1, sop & 1 ? 'R' : 'L');
5623 
5624       sL = DREG (src1);
5625       sH = DREG (src1) >> 16;
5626 
5627       if (sop & 1)
5628 	acc0 = (acc0 & 0xfeffffffffull) >> 1;
5629       else
5630 	acc0 <<= 1;
5631 
5632       if (((sH - sL) & 0x8000) == 0)
5633 	{
5634 	  out = sH;
5635 	  acc0 |= (sop & 1) ? 0x80000000 : 1;
5636 	}
5637       else
5638 	out = sL;
5639 
5640       SET_AREG (0, acc0);
5641       STORE (DREG (dst0), REG_H_L (DREG (dst0), out));
5642     }
5643   else if ((sop == 2 || sop == 3) && sopcde == 9)
5644     {
5645       bs40 acc0 = get_extended_acc (cpu, 0);
5646       bs16 s0L, s0H, s1L, s1H, out0, out1;
5647 
5648       TRACE_INSN (cpu, "R%i = VIT_MAX (R%i, R%i) (AS%c);",
5649 		  dst0, src1, src0, sop & 1 ? 'R' : 'L');
5650 
5651       s0L = DREG (src0);
5652       s0H = DREG (src0) >> 16;
5653       s1L = DREG (src1);
5654       s1H = DREG (src1) >> 16;
5655 
5656       if (sop & 1)
5657 	acc0 >>= 2;
5658       else
5659 	acc0 <<= 2;
5660 
5661       if (((s0H - s0L) & 0x8000) == 0)
5662 	{
5663 	  out0 = s0H;
5664 	  acc0 |= (sop & 1) ? 0x40000000 : 2;
5665 	}
5666       else
5667 	out0 = s0L;
5668 
5669       if (((s1H - s1L) & 0x8000) == 0)
5670 	{
5671 	  out1 = s1H;
5672 	  acc0 |= (sop & 1) ? 0x80000000 : 1;
5673 	}
5674       else
5675 	out1 = s1L;
5676 
5677       SET_AREG (0, acc0);
5678       STORE (DREG (dst0), REG_H_L (out1 << 16, out0));
5679     }
5680   else if (sop == 0 && sopcde == 10)
5681     {
5682       bu32 v = DREG (src0);
5683       bu32 x = DREG (src1);
5684       bu32 mask = (1 << (v & 0x1f)) - 1;
5685 
5686       TRACE_INSN (cpu, "R%i = EXTRACT (R%i, R%i.L) (Z);", dst0, src1, src0);
5687 
5688       x >>= ((v >> 8) & 0x1f);
5689       x &= mask;
5690       STORE (DREG (dst0), x);
5691       setflags_logical (cpu, x);
5692     }
5693   else if (sop == 1 && sopcde == 10)
5694     {
5695       bu32 v = DREG (src0);
5696       bu32 x = DREG (src1);
5697       bu32 sgn = (1 << (v & 0x1f)) >> 1;
5698       bu32 mask = (1 << (v & 0x1f)) - 1;
5699 
5700       TRACE_INSN (cpu, "R%i = EXTRACT (R%i, R%i.L) (X);", dst0, src1, src0);
5701 
5702       x >>= ((v >> 8) & 0x1f);
5703       x &= mask;
5704       if (x & sgn)
5705 	x |= ~mask;
5706       STORE (DREG (dst0), x);
5707       setflags_logical (cpu, x);
5708     }
5709   else if ((sop == 2 || sop == 3) && sopcde == 10)
5710     {
5711       /* The first dregs is the "background" while the second dregs is the
5712          "foreground".  The fg reg is used to overlay the bg reg and is:
5713          | nnnn nnnn | nnnn nnnn | xxxp pppp | xxxL LLLL |
5714            n = the fg bit field
5715            p = bit position in bg reg to start LSB of fg field
5716            L = number of fg bits to extract
5717          Using (X) sign-extends the fg bit field.  */
5718       bu32 fg = DREG (src0);
5719       bu32 bg = DREG (src1);
5720       bu32 len = fg & 0x1f;
5721       bu32 mask = (1 << min (16, len)) - 1;
5722       bu32 fgnd = (fg >> 16) & mask;
5723       int shft = ((fg >> 8) & 0x1f);
5724 
5725       TRACE_INSN (cpu, "R%i = DEPOSIT (R%i, R%i)%s;", dst0, src1, src0,
5726 		  sop == 3 ? " (X)" : "");
5727 
5728       if (sop == 3)
5729 	{
5730 	  /* Sign extend the fg bit field.  */
5731 	  mask = -1;
5732 	  fgnd = ((bs32)(bs16)(fgnd << (16 - len))) >> (16 - len);
5733 	}
5734       fgnd <<= shft;
5735       mask <<= shft;
5736       bg &= ~mask;
5737 
5738       bg |= fgnd;
5739       STORE (DREG (dst0), bg);
5740       setflags_logical (cpu, bg);
5741     }
5742   else if (sop == 0 && sopcde == 11)
5743     {
5744       bu64 acc0 = get_unextended_acc (cpu, 0);
5745 
5746       TRACE_INSN (cpu, "R%i.L = CC = BXORSHIFT (A0, R%i);", dst0, src0);
5747 
5748       acc0 <<= 1;
5749       SET_CCREG (xor_reduce (acc0, DREG (src0)));
5750       SET_DREG (dst0, REG_H_L (DREG (dst0), CCREG));
5751       SET_AREG (0, acc0);
5752     }
5753   else if (sop == 1 && sopcde == 11)
5754     {
5755       bu64 acc0 = get_unextended_acc (cpu, 0);
5756 
5757       TRACE_INSN (cpu, "R%i.L = CC = BXOR (A0, R%i);", dst0, src0);
5758 
5759       SET_CCREG (xor_reduce (acc0, DREG (src0)));
5760       SET_DREG (dst0, REG_H_L (DREG (dst0), CCREG));
5761     }
5762   else if (sop == 0 && sopcde == 12)
5763     {
5764       bu64 acc0 = get_unextended_acc (cpu, 0);
5765       bu64 acc1 = get_unextended_acc (cpu, 1);
5766 
5767       TRACE_INSN (cpu, "A0 = BXORSHIFT (A0, A1, CC);");
5768 
5769       acc0 = (acc0 << 1) | (CCREG ^ xor_reduce (acc0, acc1));
5770       SET_AREG (0, acc0);
5771     }
5772   else if (sop == 1 && sopcde == 12)
5773     {
5774       bu64 acc0 = get_unextended_acc (cpu, 0);
5775       bu64 acc1 = get_unextended_acc (cpu, 1);
5776 
5777       TRACE_INSN (cpu, "R%i.L = CC = BXOR (A0, A1, CC);", dst0);
5778 
5779       SET_CCREG (CCREG ^ xor_reduce (acc0, acc1));
5780       acc0 = (acc0 << 1) | CCREG;
5781       SET_DREG (dst0, REG_H_L (DREG (dst0), CCREG));
5782     }
5783   else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 13)
5784     {
5785       int shift = (sop + 1) * 8;
5786       TRACE_INSN (cpu, "R%i = ALIGN%i (R%i, R%i);", dst0, shift, src1, src0);
5787       STORE (DREG (dst0), (DREG (src1) << (32 - shift)) | (DREG (src0) >> shift));
5788     }
5789   else
5790     illegal_instruction (cpu);
5791 }
5792 
5793 static bu64
5794 sgn_extend (bu40 org, bu40 val, int size)
5795 {
5796   bu64 ret = val;
5797 
5798   if (org & (1ULL << (size - 1)))
5799     {
5800       /* We need to shift in to the MSB which is set.  */
5801       int n;
5802 
5803       for (n = 40; n >= 0; n--)
5804 	if (ret & (1ULL << n))
5805 	  break;
5806       ret |= (-1ULL << n);
5807     }
5808   else
5809     ret &= ~(-1ULL << 39);
5810 
5811   return ret;
5812 }
5813 static void
5814 decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
5815 {
5816   /* dsp32shiftimm
5817      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
5818      | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
5819      |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
5820      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
5821   int src1     = ((iw1 >> DSP32ShiftImm_src1_bits) & DSP32ShiftImm_src1_mask);
5822   int sop      = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
5823   int bit8     = ((iw1 >> 8) & 0x1);
5824   int immag    = ((iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
5825   int newimmag = (-(iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
5826   int dst0     = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
5827   int M        = ((iw0 >> (DSP32ShiftImm_M_bits - 16)) & DSP32ShiftImm_M_mask);
5828   int sopcde   = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
5829   int HLs      = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
5830 
5831   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32shiftimm);
5832   TRACE_EXTRACT (cpu, "%s: M:%i sopcde:%i sop:%i HLs:%i dst0:%i immag:%#x src1:%i",
5833 		 __func__, M, sopcde, sop, HLs, dst0, immag, src1);
5834 
5835   if (sopcde == 0)
5836     {
5837       bu16 in = DREG (src1) >> ((HLs & 1) ? 16 : 0);
5838       bu16 result;
5839       bu32 v;
5840 
5841       if (sop == 0)
5842 	{
5843 	  TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i;",
5844 		      dst0, (HLs & 2) ? 'H' : 'L',
5845 		      src1, (HLs & 1) ? 'H' : 'L', newimmag);
5846 	  if (newimmag > 16)
5847 	    {
5848 	      result = lshift (cpu, in, 16 - (newimmag & 0xF), 16, 0, 1);
5849 	      if (((result >> 15) & 0x1) != ((in >> 15) & 0x1))
5850 		{
5851 		  SET_ASTATREG (v, 1);
5852 		  SET_ASTATREG (vs, 1);
5853 		}
5854 	    }
5855 	  else
5856 	    result = ashiftrt (cpu, in, newimmag, 16);
5857 	}
5858       else if (sop == 1 && bit8 == 0)
5859 	{
5860 	  TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i (S);",
5861 		      dst0, (HLs & 2) ? 'H' : 'L',
5862 		      src1, (HLs & 1) ? 'H' : 'L', immag);
5863 	  result = lshift (cpu, in, immag, 16, 1, 1);
5864 	}
5865       else if (sop == 1 && bit8)
5866 	{
5867 	  TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i (S);",
5868 		      dst0, (HLs & 2) ? 'H' : 'L',
5869 		      src1, (HLs & 1) ? 'H' : 'L', newimmag);
5870 	  if (newimmag > 16)
5871 	    {
5872 	      int shift = 32 - newimmag;
5873 	      bu16 inshift = in << shift;
5874 
5875 	      if (((inshift & ~0xFFFF)
5876 		   && ((inshift & ~0xFFFF) >> 16) != ~(~0 << shift))
5877 		  || (inshift & 0x8000) != (in & 0x8000))
5878 		{
5879 		  if (in & 0x8000)
5880 		    result = 0x8000;
5881 		  else
5882 		    result = 0x7fff;
5883 		  SET_ASTATREG (v, 1);
5884 		  SET_ASTATREG (vs, 1);
5885 		}
5886 	      else
5887 		{
5888 		  result = inshift;
5889 		  SET_ASTATREG (v, 0);
5890 		}
5891 
5892 	      SET_ASTATREG (az, !result);
5893 	      SET_ASTATREG (an, !!(result & 0x8000));
5894 	    }
5895 	  else
5896 	    {
5897 	      result = ashiftrt (cpu, in, newimmag, 16);
5898 	      result = sgn_extend (in, result, 16);
5899 	    }
5900 	}
5901       else if (sop == 2 && bit8)
5902 	{
5903 	  TRACE_INSN (cpu, "R%i.%c = R%i.%c >> %i;",
5904 		      dst0, (HLs & 2) ? 'H' : 'L',
5905 		      src1, (HLs & 1) ? 'H' : 'L', newimmag);
5906 	  result = lshiftrt (cpu, in, newimmag, 16);
5907 	}
5908       else if (sop == 2 && bit8 == 0)
5909 	{
5910 	  TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i;",
5911 		      dst0, (HLs & 2) ? 'H' : 'L',
5912 		      src1, (HLs & 1) ? 'H' : 'L', immag);
5913 	  result = lshift (cpu, in, immag, 16, 0, 1);
5914 	}
5915       else
5916 	illegal_instruction (cpu);
5917 
5918       v = DREG (dst0);
5919       if (HLs & 2)
5920 	STORE (DREG (dst0), (v & 0xFFFF) | (result << 16));
5921       else
5922 	STORE (DREG (dst0), (v & 0xFFFF0000) | result);
5923     }
5924   else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0))
5925     {
5926       int shift = imm6 (immag);
5927       bu32 cc = CCREG;
5928       bu40 acc = get_unextended_acc (cpu, HLs);
5929 
5930       TRACE_INSN (cpu, "A%i = ROT A%i BY %i;", HLs, HLs, shift);
5931       TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc);
5932 
5933       acc = rot40 (acc, shift, &cc);
5934       SET_AREG (HLs, acc);
5935       if (shift)
5936 	SET_CCREG (cc);
5937     }
5938   else if (sop == 0 && sopcde == 3 && bit8 == 1 && HLs < 2)
5939     {
5940       /* Arithmetic shift, so shift in sign bit copies.  */
5941       bu64 acc, val;
5942       int shift = uimm5 (newimmag);
5943 
5944       TRACE_INSN (cpu, "A%i = A%i >>> %i;", HLs, HLs, shift);
5945 
5946       acc = get_extended_acc (cpu, HLs);
5947       val = acc >> shift;
5948 
5949       /* Sign extend again.  */
5950       val = sgn_extend (acc, val, 40);
5951 
5952       STORE (AXREG (HLs), (val >> 32) & 0xFF);
5953       STORE (AWREG (HLs), val & 0xFFFFFFFF);
5954       STORE (ASTATREG (an), !!(val & (1ULL << 39)));
5955       STORE (ASTATREG (az), !val);
5956       STORE (ASTATREG (av[HLs]), 0);
5957     }
5958   else if (((sop == 0 && sopcde == 3 && bit8 == 0)
5959 	   || (sop == 1 && sopcde == 3)) && HLs < 2)
5960     {
5961       bu64 acc;
5962       int shiftup = uimm5 (immag);
5963       int shiftdn = uimm5 (newimmag);
5964 
5965       TRACE_INSN (cpu, "A%i = A%i %s %i;", HLs, HLs,
5966 		  sop == 0 ? "<<" : ">>",
5967 		  sop == 0 ? shiftup : shiftdn);
5968 
5969       acc = AXREG (HLs);
5970       /* Logical shift, so shift in zeroes.  */
5971       acc &= 0xFF;
5972       acc <<= 32;
5973       acc |= AWREG (HLs);
5974 
5975       if (sop == 0)
5976 	acc <<= shiftup;
5977       else
5978 	{
5979 	  if (shiftdn <= 32)
5980 	    acc >>= shiftdn;
5981 	  else
5982 	    acc <<= 32 - (shiftdn & 0x1f);
5983 	}
5984 
5985       SET_AREG (HLs, acc);
5986       SET_ASTATREG (av[HLs], 0);
5987       SET_ASTATREG (an, !!(acc & 0x8000000000ull));
5988       SET_ASTATREG (az, (acc & 0xFFFFFFFFFF) == 0);
5989     }
5990   else if (HLs != 0)
5991     /* All the insns after this point don't use HLs.  */
5992     illegal_instruction (cpu);
5993   else if (sop == 1 && sopcde == 1 && bit8 == 0)
5994     {
5995       int count = imm5 (immag);
5996       bu16 val0 = DREG (src1) >> 16;
5997       bu16 val1 = DREG (src1) & 0xFFFF;
5998       bu32 astat;
5999 
6000       TRACE_INSN (cpu, "R%i = R%i << %i (V,S);", dst0, src1, count);
6001       if (count >= 0)
6002 	{
6003 	  val0 = lshift (cpu, val0, count, 16, 1, 1);
6004 	  astat = ASTAT;
6005 	  val1 = lshift (cpu, val1, count, 16, 1, 1);
6006 	}
6007       else
6008 	{
6009 	  val0 = ashiftrt (cpu, val0, -count, 16);
6010 	  astat = ASTAT;
6011 	  val1 = ashiftrt (cpu, val1, -count, 16);
6012 	}
6013       SET_ASTAT (ASTAT | astat);
6014 
6015       STORE (DREG (dst0), (val0 << 16) | val1);
6016     }
6017   else if (sop == 2 && sopcde == 1 && bit8 == 1)
6018     {
6019       int count = imm5 (newimmag);
6020       bu16 val0 = DREG (src1) & 0xFFFF;
6021       bu16 val1 = DREG (src1) >> 16;
6022       bu32 astat;
6023 
6024       TRACE_INSN (cpu, "R%i = R%i >> %i (V);", dst0, src1, count);
6025       val0 = lshiftrt (cpu, val0, count, 16);
6026       astat = ASTAT;
6027       val1 = lshiftrt (cpu, val1, count, 16);
6028       SET_ASTAT (ASTAT | astat);
6029 
6030       STORE (DREG (dst0), val0 | (val1 << 16));
6031     }
6032   else if (sop == 2 && sopcde == 1 && bit8 == 0)
6033     {
6034       int count = imm5 (immag);
6035       bu16 val0 = DREG (src1) & 0xFFFF;
6036       bu16 val1 = DREG (src1) >> 16;
6037       bu32 astat;
6038 
6039       TRACE_INSN (cpu, "R%i = R%i << %i (V);", dst0, src1, count);
6040       val0 = lshift (cpu, val0, count, 16, 0, 1);
6041       astat = ASTAT;
6042       val1 = lshift (cpu, val1, count, 16, 0, 1);
6043       SET_ASTAT (ASTAT | astat);
6044 
6045       STORE (DREG (dst0), val0 | (val1 << 16));
6046     }
6047   else if (sopcde == 1 && (sop == 0 || (sop == 1 && bit8 == 1)))
6048     {
6049       int count = uimm5 (newimmag);
6050       bu16 val0 = DREG (src1) & 0xFFFF;
6051       bu16 val1 = DREG (src1) >> 16;
6052       bu32 astat;
6053 
6054       TRACE_INSN (cpu, "R%i = R%i >>> %i %s;", dst0, src1, count,
6055 		  sop == 0 ? "(V)" : "(V,S)");
6056 
6057       if (count > 16)
6058 	{
6059 	  int sgn0 = (val0 >> 15) & 0x1;
6060 	  int sgn1 = (val1 >> 15) & 0x1;
6061 
6062 	  val0 = lshift (cpu, val0, 16 - (count & 0xF), 16, 0, 1);
6063 	  astat = ASTAT;
6064 	  val1 = lshift (cpu, val1, 16 - (count & 0xF), 16, 0, 1);
6065 
6066 	  if ((sgn0 != ((val0 >> 15) & 0x1)) || (sgn1 != ((val1 >> 15) & 0x1)))
6067 	    {
6068 	      SET_ASTATREG (v, 1);
6069 	      SET_ASTATREG (vs, 1);
6070 	    }
6071 	}
6072       else
6073 	{
6074 	  val0 = ashiftrt (cpu, val0, count, 16);
6075 	  astat = ASTAT;
6076 	  val1 = ashiftrt (cpu, val1, count, 16);
6077 	}
6078 
6079       SET_ASTAT (ASTAT | astat);
6080 
6081       STORE (DREG (dst0), REG_H_L (val1 << 16, val0));
6082     }
6083   else if (sop == 1 && sopcde == 2)
6084     {
6085       int count = imm6 (immag);
6086 
6087       TRACE_INSN (cpu, "R%i = R%i << %i (S);", dst0, src1, count);
6088 
6089       if (count < 0)
6090 	STORE (DREG (dst0), ashiftrt (cpu, DREG (src1), -count, 32));
6091       else
6092 	STORE (DREG (dst0), lshift (cpu, DREG (src1), count, 32, 1, 1));
6093     }
6094   else if (sop == 2 && sopcde == 2)
6095     {
6096       int count = imm6 (newimmag);
6097 
6098       TRACE_INSN (cpu, "R%i = R%i >> %i;", dst0, src1, count);
6099 
6100       if (count < 0)
6101 	STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0, 1));
6102       else
6103 	STORE (DREG (dst0), lshiftrt (cpu, DREG (src1), count, 32));
6104     }
6105   else if (sop == 3 && sopcde == 2)
6106     {
6107       int shift = imm6 (immag);
6108       bu32 src = DREG (src1);
6109       bu32 ret, cc = CCREG;
6110 
6111       TRACE_INSN (cpu, "R%i = ROT R%i BY %i;", dst0, src1, shift);
6112       TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i",
6113 		    dst0, DREG (dst0), src1, src, shift, cc);
6114 
6115       ret = rot32 (src, shift, &cc);
6116       STORE (DREG (dst0), ret);
6117       if (shift)
6118 	SET_CCREG (cc);
6119     }
6120   else if (sop == 0 && sopcde == 2)
6121     {
6122       int count = imm6 (newimmag);
6123 
6124       TRACE_INSN (cpu, "R%i = R%i >>> %i;", dst0, src1, count);
6125 
6126       if (count < 0)
6127 	STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0, 1));
6128       else
6129 	STORE (DREG (dst0), ashiftrt (cpu, DREG (src1), count, 32));
6130     }
6131   else
6132     illegal_instruction (cpu);
6133 }
6134 
6135 static void
6136 outc (SIM_CPU *cpu, char ch)
6137 {
6138   SIM_DESC sd = CPU_STATE (cpu);
6139   sim_io_printf (sd, "%c", ch);
6140   if (ch == '\n')
6141     sim_io_flush_stdout (sd);
6142 }
6143 
6144 static void
6145 decode_psedoDEBUG_0 (SIM_CPU *cpu, bu16 iw0)
6146 {
6147   /* psedoDEBUG
6148      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
6149      | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |.fn....|.grp.......|.reg.......|
6150      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
6151   SIM_DESC sd = CPU_STATE (cpu);
6152   int fn  = ((iw0 >> PseudoDbg_fn_bits) & PseudoDbg_fn_mask);
6153   int grp = ((iw0 >> PseudoDbg_grp_bits) & PseudoDbg_grp_mask);
6154   int reg = ((iw0 >> PseudoDbg_reg_bits) & PseudoDbg_reg_mask);
6155 
6156   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_psedoDEBUG);
6157   TRACE_EXTRACT (cpu, "%s: fn:%i grp:%i reg:%i", __func__, fn, grp, reg);
6158 
6159   if ((reg == 0 || reg == 1) && fn == 3)
6160     {
6161       TRACE_INSN (cpu, "DBG A%i;", reg);
6162       sim_io_printf (sd, "DBG : A%i = %#"PRIx64"\n", reg,
6163 		     get_unextended_acc (cpu, reg));
6164     }
6165   else if (reg == 3 && fn == 3)
6166     {
6167       TRACE_INSN (cpu, "ABORT;");
6168       cec_exception (cpu, VEC_SIM_ABORT);
6169       SET_DREG (0, 1);
6170     }
6171   else if (reg == 4 && fn == 3)
6172     {
6173       TRACE_INSN (cpu, "HLT;");
6174       cec_exception (cpu, VEC_SIM_HLT);
6175       SET_DREG (0, 0);
6176     }
6177   else if (reg == 5 && fn == 3)
6178     unhandled_instruction (cpu, "DBGHALT");
6179   else if (reg == 6 && fn == 3)
6180     unhandled_instruction (cpu, "DBGCMPLX (dregs)");
6181   else if (reg == 7 && fn == 3)
6182     unhandled_instruction (cpu, "DBG");
6183   else if (grp == 0 && fn == 2)
6184     {
6185       TRACE_INSN (cpu, "OUTC R%i;", reg);
6186       outc (cpu, DREG (reg));
6187     }
6188   else if (fn == 0)
6189     {
6190       const char *reg_name = get_allreg_name (grp, reg);
6191       TRACE_INSN (cpu, "DBG %s;", reg_name);
6192       sim_io_printf (sd, "DBG : %s = 0x%08x\n", reg_name,
6193 		     reg_read (cpu, grp, reg));
6194     }
6195   else if (fn == 1)
6196     unhandled_instruction (cpu, "PRNT allregs");
6197   else
6198     illegal_instruction (cpu);
6199 }
6200 
6201 static void
6202 decode_psedoOChar_0 (SIM_CPU *cpu, bu16 iw0)
6203 {
6204   /* psedoOChar
6205      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
6206      | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |.ch............................|
6207      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
6208   int ch = ((iw0 >> PseudoChr_ch_bits) & PseudoChr_ch_mask);
6209 
6210   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_psedoOChar);
6211   TRACE_EXTRACT (cpu, "%s: ch:%#x", __func__, ch);
6212   TRACE_INSN (cpu, "OUTC %#x;", ch);
6213 
6214   outc (cpu, ch);
6215 }
6216 
6217 static void
6218 decode_psedodbg_assert_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1, bu32 pc)
6219 {
6220   /* psedodbg_assert
6221      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
6222      | 1 | 1 | 1 | 1 | 0 | - | - | - | dbgop |.grp.......|.regtest...|
6223      |.expected......................................................|
6224      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
6225   SIM_DESC sd = CPU_STATE (cpu);
6226   int expected = ((iw1 >> PseudoDbg_Assert_expected_bits) & PseudoDbg_Assert_expected_mask);
6227   int dbgop    = ((iw0 >> (PseudoDbg_Assert_dbgop_bits - 16)) & PseudoDbg_Assert_dbgop_mask);
6228   int grp      = ((iw0 >> (PseudoDbg_Assert_grp_bits - 16)) & PseudoDbg_Assert_grp_mask);
6229   int regtest  = ((iw0 >> (PseudoDbg_Assert_regtest_bits - 16)) & PseudoDbg_Assert_regtest_mask);
6230   int offset;
6231   bu16 actual;
6232   bu32 val = reg_read (cpu, grp, regtest);
6233   const char *reg_name = get_allreg_name (grp, regtest);
6234   const char *dbg_name, *dbg_appd;
6235 
6236   PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_psedodbg_assert);
6237   TRACE_EXTRACT (cpu, "%s: dbgop:%i grp:%i regtest:%i expected:%#x",
6238 		 __func__, dbgop, grp, regtest, expected);
6239 
6240   if (dbgop == 0 || dbgop == 2)
6241     {
6242       dbg_name = dbgop == 0 ? "DBGA" : "DBGAL";
6243       dbg_appd = dbgop == 0 ? ".L" : "";
6244       offset = 0;
6245     }
6246   else if (dbgop == 1 || dbgop == 3)
6247     {
6248       dbg_name = dbgop == 1 ? "DBGA" : "DBGAH";
6249       dbg_appd = dbgop == 1 ? ".H" : "";
6250       offset = 16;
6251     }
6252   else
6253     illegal_instruction (cpu);
6254 
6255   actual = val >> offset;
6256 
6257   TRACE_INSN (cpu, "%s (%s%s, 0x%x);", dbg_name, reg_name, dbg_appd, expected);
6258   if (actual != expected)
6259     {
6260       sim_io_printf (sd, "FAIL at %#x: %s (%s%s, 0x%04x); actual value %#x\n",
6261 		     pc, dbg_name, reg_name, dbg_appd, expected, actual);
6262 
6263       /* Decode the actual ASTAT bits that are different.  */
6264       if (grp == 4 && regtest == 6)
6265 	{
6266 	  int i;
6267 
6268 	  sim_io_printf (sd, "Expected ASTAT:\n");
6269 	  for (i = 0; i < 16; ++i)
6270 	    sim_io_printf (sd, " %8s%c%i%s",
6271 			   astat_names[i + offset],
6272 			   (((expected >> i) & 1) != ((actual >> i) & 1))
6273 				? '!' : ' ',
6274 			   (expected >> i) & 1,
6275 			   i == 7 ? "\n" : "");
6276 	  sim_io_printf (sd, "\n");
6277 
6278 	  sim_io_printf (sd, "Actual ASTAT:\n");
6279 	  for (i = 0; i < 16; ++i)
6280 	    sim_io_printf (sd, " %8s%c%i%s",
6281 			   astat_names[i + offset],
6282 			   (((expected >> i) & 1) != ((actual >> i) & 1))
6283 				? '!' : ' ',
6284 			   (actual >> i) & 1,
6285 			   i == 7 ? "\n" : "");
6286 	  sim_io_printf (sd, "\n");
6287 	}
6288 
6289       cec_exception (cpu, VEC_SIM_DBGA);
6290       SET_DREG (0, 1);
6291     }
6292 }
6293 
6294 static bu32
6295 _interp_insn_bfin (SIM_CPU *cpu, bu32 pc)
6296 {
6297   bu32 insn_len;
6298   bu16 iw0, iw1;
6299 
6300   BFIN_CPU_STATE.multi_pc = pc;
6301   iw0 = IFETCH (pc);
6302   if ((iw0 & 0xc000) != 0xc000)
6303     {
6304       /* 16-bit opcode.  */
6305       insn_len = 2;
6306       if (INSN_LEN == 0)
6307 	INSN_LEN = insn_len;
6308 
6309       TRACE_EXTRACT (cpu, "%s: iw0:%#x", __func__, iw0);
6310       if ((iw0 & 0xFF00) == 0x0000)
6311 	decode_ProgCtrl_0 (cpu, iw0, pc);
6312       else if ((iw0 & 0xFFC0) == 0x0240)
6313 	decode_CaCTRL_0 (cpu, iw0);
6314       else if ((iw0 & 0xFF80) == 0x0100)
6315 	decode_PushPopReg_0 (cpu, iw0);
6316       else if ((iw0 & 0xFE00) == 0x0400)
6317 	decode_PushPopMultiple_0 (cpu, iw0);
6318       else if ((iw0 & 0xFE00) == 0x0600)
6319 	decode_ccMV_0 (cpu, iw0);
6320       else if ((iw0 & 0xF800) == 0x0800)
6321 	decode_CCflag_0 (cpu, iw0);
6322       else if ((iw0 & 0xFFE0) == 0x0200)
6323 	decode_CC2dreg_0 (cpu, iw0);
6324       else if ((iw0 & 0xFF00) == 0x0300)
6325 	decode_CC2stat_0 (cpu, iw0);
6326       else if ((iw0 & 0xF000) == 0x1000)
6327 	decode_BRCC_0 (cpu, iw0, pc);
6328       else if ((iw0 & 0xF000) == 0x2000)
6329 	decode_UJUMP_0 (cpu, iw0, pc);
6330       else if ((iw0 & 0xF000) == 0x3000)
6331 	decode_REGMV_0 (cpu, iw0);
6332       else if ((iw0 & 0xFC00) == 0x4000)
6333 	decode_ALU2op_0 (cpu, iw0);
6334       else if ((iw0 & 0xFE00) == 0x4400)
6335 	decode_PTR2op_0 (cpu, iw0);
6336       else if ((iw0 & 0xF800) == 0x4800)
6337 	decode_LOGI2op_0 (cpu, iw0);
6338       else if ((iw0 & 0xF000) == 0x5000)
6339 	decode_COMP3op_0 (cpu, iw0);
6340       else if ((iw0 & 0xF800) == 0x6000)
6341 	decode_COMPI2opD_0 (cpu, iw0);
6342       else if ((iw0 & 0xF800) == 0x6800)
6343 	decode_COMPI2opP_0 (cpu, iw0);
6344       else if ((iw0 & 0xF000) == 0x8000)
6345 	decode_LDSTpmod_0 (cpu, iw0);
6346       else if ((iw0 & 0xFF60) == 0x9E60)
6347 	decode_dagMODim_0 (cpu, iw0);
6348       else if ((iw0 & 0xFFF0) == 0x9F60)
6349 	decode_dagMODik_0 (cpu, iw0);
6350       else if ((iw0 & 0xFC00) == 0x9C00)
6351 	decode_dspLDST_0 (cpu, iw0);
6352       else if ((iw0 & 0xF000) == 0x9000)
6353 	decode_LDST_0 (cpu, iw0);
6354       else if ((iw0 & 0xFC00) == 0xB800)
6355 	decode_LDSTiiFP_0 (cpu, iw0);
6356       else if ((iw0 & 0xE000) == 0xA000)
6357 	decode_LDSTii_0 (cpu, iw0);
6358       else
6359 	{
6360 	  TRACE_EXTRACT (cpu, "%s: no matching 16-bit pattern", __func__);
6361 	  illegal_instruction_or_combination (cpu);
6362 	}
6363       return insn_len;
6364     }
6365 
6366   /* Grab the next 16 bits to determine if it's a 32-bit or 64-bit opcode.  */
6367   iw1 = IFETCH (pc + 2);
6368   if ((iw0 & BIT_MULTI_INS) && (iw0 & 0xe800) != 0xe800 /* not linkage  */)
6369     {
6370       SIM_DESC sd = CPU_STATE (cpu);
6371       trace_prefix (sd, cpu, NULL_CIA, pc, TRACE_LINENUM_P (cpu),
6372 			NULL, 0, "|| %#"PRIx64, sim_events_time (sd));
6373       insn_len = 8;
6374       PARALLEL_GROUP = BFIN_PARALLEL_GROUP0;
6375     }
6376   else
6377     insn_len = 4;
6378 
6379   TRACE_EXTRACT (cpu, "%s: iw0:%#x iw1:%#x insn_len:%i", __func__,
6380 		     iw0, iw1, insn_len);
6381 
6382   /* Only cache on first run through (in case of parallel insns).  */
6383   if (INSN_LEN == 0)
6384     INSN_LEN = insn_len;
6385   else
6386     /* Once you're past the first slot, only 16bit insns are valid.  */
6387     illegal_instruction_combination (cpu);
6388 
6389   if ((iw0 & 0xf7ff) == 0xc003 && (iw1 & 0xfe00) == 0x1800)
6390     {
6391       PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mac);
6392       TRACE_INSN (cpu, "MNOP;");
6393     }
6394   else if (((iw0 & 0xFF80) == 0xE080) && ((iw1 & 0x0C00) == 0x0000))
6395     decode_LoopSetup_0 (cpu, iw0, iw1, pc);
6396   else if (((iw0 & 0xFF00) == 0xE100) && ((iw1 & 0x0000) == 0x0000))
6397     decode_LDIMMhalf_0 (cpu, iw0, iw1);
6398   else if (((iw0 & 0xFE00) == 0xE200) && ((iw1 & 0x0000) == 0x0000))
6399     decode_CALLa_0 (cpu, iw0, iw1, pc);
6400   else if (((iw0 & 0xFC00) == 0xE400) && ((iw1 & 0x0000) == 0x0000))
6401     decode_LDSTidxI_0 (cpu, iw0, iw1);
6402   else if (((iw0 & 0xFFFE) == 0xE800) && ((iw1 & 0x0000) == 0x0000))
6403     decode_linkage_0 (cpu, iw0, iw1);
6404   else if (((iw0 & 0xF600) == 0xC000) && ((iw1 & 0x0000) == 0x0000))
6405     decode_dsp32mac_0 (cpu, iw0, iw1);
6406   else if (((iw0 & 0xF600) == 0xC200) && ((iw1 & 0x0000) == 0x0000))
6407     decode_dsp32mult_0 (cpu, iw0, iw1);
6408   else if (((iw0 & 0xF7C0) == 0xC400) && ((iw1 & 0x0000) == 0x0000))
6409     decode_dsp32alu_0 (cpu, iw0, iw1);
6410   else if (((iw0 & 0xF7E0) == 0xC600) && ((iw1 & 0x01C0) == 0x0000))
6411     decode_dsp32shift_0 (cpu, iw0, iw1);
6412   else if (((iw0 & 0xF7E0) == 0xC680) && ((iw1 & 0x0000) == 0x0000))
6413     decode_dsp32shiftimm_0 (cpu, iw0, iw1);
6414   else if ((iw0 & 0xFF00) == 0xF800)
6415     decode_psedoDEBUG_0 (cpu, iw0), insn_len = 2;
6416   else if ((iw0 & 0xFF00) == 0xF900)
6417     decode_psedoOChar_0 (cpu, iw0), insn_len = 2;
6418   else if (((iw0 & 0xFF00) == 0xF000) && ((iw1 & 0x0000) == 0x0000))
6419     decode_psedodbg_assert_0 (cpu, iw0, iw1, pc);
6420   else
6421     {
6422       TRACE_EXTRACT (cpu, "%s: no matching 32-bit pattern", __func__);
6423       illegal_instruction (cpu);
6424     }
6425 
6426   return insn_len;
6427 }
6428 
6429 bu32
6430 interp_insn_bfin (SIM_CPU *cpu, bu32 pc)
6431 {
6432   int i;
6433   bu32 insn_len;
6434 
6435   BFIN_CPU_STATE.n_stores = 0;
6436   PARALLEL_GROUP = BFIN_PARALLEL_NONE;
6437   DIS_ALGN_EXPT &= ~1;
6438   CYCLE_DELAY = 1;
6439   INSN_LEN = 0;
6440 
6441   insn_len = _interp_insn_bfin (cpu, pc);
6442 
6443   /* Proper display of multiple issue instructions.  */
6444   if (insn_len == 8)
6445     {
6446       PARALLEL_GROUP = BFIN_PARALLEL_GROUP1;
6447       _interp_insn_bfin (cpu, pc + 4);
6448       PARALLEL_GROUP = BFIN_PARALLEL_GROUP2;
6449       _interp_insn_bfin (cpu, pc + 6);
6450     }
6451   for (i = 0; i < BFIN_CPU_STATE.n_stores; i++)
6452     {
6453       bu32 *addr = BFIN_CPU_STATE.stores[i].addr;
6454       *addr = BFIN_CPU_STATE.stores[i].val;
6455       TRACE_REGISTER (cpu, "dequeuing write %s = %#x",
6456 		      get_store_name (cpu, addr), *addr);
6457     }
6458 
6459   cycles_inc (cpu, CYCLE_DELAY);
6460 
6461   /* Set back to zero in case a pending CEC event occurs
6462      after this this insn.  */
6463   INSN_LEN = 0;
6464 
6465   return insn_len;
6466 }
6467