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