Home | History | Annotate | Line # | Download | only in mips
mdmx.c revision 1.1.1.2
      1      1.1  christos /* Simulation code for the MIPS MDMX ASE.
      2  1.1.1.2  christos    Copyright (C) 2002-2013 Free Software Foundation, Inc.
      3      1.1  christos    Contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom
      4      1.1  christos    Corporation (SiByte).
      5      1.1  christos 
      6      1.1  christos This file is part of GDB, the GNU debugger.
      7      1.1  christos 
      8      1.1  christos This program is free software; you can redistribute it and/or modify
      9      1.1  christos it under the terms of the GNU General Public License as published by
     10      1.1  christos the Free Software Foundation; either version 3 of the License, or
     11      1.1  christos (at your option) any later version.
     12      1.1  christos 
     13      1.1  christos This program is distributed in the hope that it will be useful,
     14      1.1  christos but WITHOUT ANY WARRANTY; without even the implied warranty of
     15      1.1  christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16      1.1  christos GNU General Public License for more details.
     17      1.1  christos 
     18      1.1  christos You should have received a copy of the GNU General Public License
     19      1.1  christos along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20      1.1  christos 
     21      1.1  christos #include <stdio.h>
     22      1.1  christos 
     23      1.1  christos #include "sim-main.h"
     24      1.1  christos 
     25      1.1  christos /* Within mdmx.c we refer to the sim_cpu directly. */
     26      1.1  christos #define CPU cpu
     27      1.1  christos #define SD  (CPU_STATE(CPU))
     28      1.1  christos 
     29      1.1  christos /* XXX FIXME: temporary hack while the impact of making unpredictable()
     30      1.1  christos    a "normal" (non-igen) function is evaluated.  */
     31      1.1  christos #undef Unpredictable
     32      1.1  christos #define Unpredictable() unpredictable_action (cpu, cia)
     33      1.1  christos 
     34      1.1  christos /* MDMX Representations
     35      1.1  christos 
     36      1.1  christos    An 8-bit packed byte element (OB) is always unsigned.
     37      1.1  christos    The 24-bit accumulators are signed and are represented as 32-bit
     38      1.1  christos    signed values, which are reduced to 24-bit signed values prior to
     39      1.1  christos    Round and Clamp operations.
     40      1.1  christos 
     41      1.1  christos    A 16-bit packed halfword element (QH) is always signed.
     42      1.1  christos    The 48-bit accumulators are signed and are represented as 64-bit
     43      1.1  christos    signed values, which are reduced to 48-bit signed values prior to
     44      1.1  christos    Round and Clamp operations.
     45      1.1  christos 
     46      1.1  christos    The code below assumes a 2's-complement representation of signed
     47      1.1  christos    quantities.  Care is required to clear extended sign bits when
     48      1.1  christos    repacking fields.
     49      1.1  christos 
     50      1.1  christos    The code (and the code for arithmetic shifts in mips.igen) also makes
     51      1.1  christos    the (not guaranteed portable) assumption that right shifts of signed
     52      1.1  christos    quantities in C do sign extension.  */
     53      1.1  christos 
     54      1.1  christos typedef unsigned64 unsigned48;
     55      1.1  christos #define MASK48 (UNSIGNED64 (0xffffffffffff))
     56      1.1  christos 
     57      1.1  christos typedef unsigned32 unsigned24;
     58      1.1  christos #define MASK24 (UNSIGNED32 (0xffffff))
     59      1.1  christos 
     60      1.1  christos typedef enum {
     61      1.1  christos   mdmx_ob,          /* OB (octal byte) */
     62      1.1  christos   mdmx_qh           /* QH (quad half-word) */
     63      1.1  christos } MX_fmt;
     64      1.1  christos 
     65      1.1  christos typedef enum {
     66      1.1  christos   sel_elem,         /* element select */
     67      1.1  christos   sel_vect,         /* vector select */
     68      1.1  christos   sel_imm           /* immediate select */
     69      1.1  christos } VT_select;
     70      1.1  christos 
     71      1.1  christos #define OB_MAX  ((unsigned8)0xFF)
     72      1.1  christos #define QH_MIN  ((signed16)0x8000)
     73      1.1  christos #define QH_MAX  ((signed16)0x7FFF)
     74      1.1  christos 
     75      1.1  christos #define OB_CLAMP(x)  ((unsigned8)((x) > OB_MAX ? OB_MAX : (x)))
     76      1.1  christos #define QH_CLAMP(x)  ((signed16)((x) < QH_MIN ? QH_MIN : \
     77      1.1  christos                                 ((x) > QH_MAX ? QH_MAX : (x))))
     78      1.1  christos 
     79      1.1  christos #define MX_FMT(fmtsel) (((fmtsel) & 0x1) == 0 ? mdmx_ob : mdmx_qh)
     80      1.1  christos #define MX_VT(fmtsel)  (((fmtsel) & 0x10) == 0 ?    sel_elem : \
     81      1.1  christos                        (((fmtsel) & 0x18) == 0x10 ? sel_vect : sel_imm))
     82      1.1  christos 
     83      1.1  christos #define QH_ELEM(v,fmtsel) \
     84      1.1  christos         ((signed16)(((v) >> (((fmtsel) & 0xC) << 2)) & 0xFFFF))
     85      1.1  christos #define OB_ELEM(v,fmtsel) \
     86      1.1  christos         ((unsigned8)(((v) >> (((fmtsel) & 0xE) << 2)) & 0xFF))
     87      1.1  christos 
     88      1.1  christos 
     89      1.1  christos typedef signed16 (*QH_FUNC)(signed16, signed16);
     90      1.1  christos typedef unsigned8 (*OB_FUNC)(unsigned8, unsigned8);
     91      1.1  christos 
     92      1.1  christos /* vectorized logical operators */
     93      1.1  christos 
     94      1.1  christos static signed16
     95      1.1  christos AndQH(signed16 ts, signed16 tt)
     96      1.1  christos {
     97      1.1  christos   return (signed16)((unsigned16)ts & (unsigned16)tt);
     98      1.1  christos }
     99      1.1  christos 
    100      1.1  christos static unsigned8
    101      1.1  christos AndOB(unsigned8 ts, unsigned8 tt)
    102      1.1  christos {
    103      1.1  christos   return ts & tt;
    104      1.1  christos }
    105      1.1  christos 
    106      1.1  christos static signed16
    107      1.1  christos NorQH(signed16 ts, signed16 tt)
    108      1.1  christos {
    109      1.1  christos   return (signed16)(((unsigned16)ts | (unsigned16)tt) ^ 0xFFFF);
    110      1.1  christos }
    111      1.1  christos 
    112      1.1  christos static unsigned8
    113      1.1  christos NorOB(unsigned8 ts, unsigned8 tt)
    114      1.1  christos {
    115      1.1  christos   return (ts | tt) ^ 0xFF;
    116      1.1  christos }
    117      1.1  christos 
    118      1.1  christos static signed16
    119      1.1  christos OrQH(signed16 ts, signed16 tt)
    120      1.1  christos {
    121      1.1  christos   return (signed16)((unsigned16)ts | (unsigned16)tt);
    122      1.1  christos }
    123      1.1  christos 
    124      1.1  christos static unsigned8
    125      1.1  christos OrOB(unsigned8 ts, unsigned8 tt)
    126      1.1  christos {
    127      1.1  christos   return ts | tt;
    128      1.1  christos }
    129      1.1  christos 
    130      1.1  christos static signed16
    131      1.1  christos XorQH(signed16 ts, signed16 tt)
    132      1.1  christos {
    133      1.1  christos   return (signed16)((unsigned16)ts ^ (unsigned16)tt);
    134      1.1  christos }
    135      1.1  christos 
    136      1.1  christos static unsigned8
    137      1.1  christos XorOB(unsigned8 ts, unsigned8 tt)
    138      1.1  christos {
    139      1.1  christos   return ts ^ tt;
    140      1.1  christos }
    141      1.1  christos 
    142      1.1  christos static signed16
    143      1.1  christos SLLQH(signed16 ts, signed16 tt)
    144      1.1  christos {
    145      1.1  christos   unsigned32 s = (unsigned32)tt & 0xF;
    146      1.1  christos   return (signed16)(((unsigned32)ts << s) & 0xFFFF);
    147      1.1  christos }
    148      1.1  christos 
    149      1.1  christos static unsigned8
    150      1.1  christos SLLOB(unsigned8 ts, unsigned8 tt)
    151      1.1  christos {
    152      1.1  christos   unsigned32 s = tt & 0x7;
    153      1.1  christos   return (ts << s) & 0xFF;
    154      1.1  christos }
    155      1.1  christos 
    156      1.1  christos static signed16
    157      1.1  christos SRLQH(signed16 ts, signed16 tt)
    158      1.1  christos {
    159      1.1  christos   unsigned32 s = (unsigned32)tt & 0xF;
    160      1.1  christos   return (signed16)((unsigned16)ts >> s);
    161      1.1  christos }
    162      1.1  christos 
    163      1.1  christos static unsigned8
    164      1.1  christos SRLOB(unsigned8 ts, unsigned8 tt)
    165      1.1  christos {
    166      1.1  christos   unsigned32 s = tt & 0x7;
    167      1.1  christos   return ts >> s;
    168      1.1  christos }
    169      1.1  christos 
    170      1.1  christos 
    171      1.1  christos /* Vectorized arithmetic operators.  */
    172      1.1  christos 
    173      1.1  christos static signed16
    174      1.1  christos AddQH(signed16 ts, signed16 tt)
    175      1.1  christos {
    176      1.1  christos   signed32 t = (signed32)ts + (signed32)tt;
    177      1.1  christos   return QH_CLAMP(t);
    178      1.1  christos }
    179      1.1  christos 
    180      1.1  christos static unsigned8
    181      1.1  christos AddOB(unsigned8 ts, unsigned8 tt)
    182      1.1  christos {
    183      1.1  christos   unsigned32 t = (unsigned32)ts + (unsigned32)tt;
    184      1.1  christos   return OB_CLAMP(t);
    185      1.1  christos }
    186      1.1  christos 
    187      1.1  christos static signed16
    188      1.1  christos SubQH(signed16 ts, signed16 tt)
    189      1.1  christos {
    190      1.1  christos   signed32 t = (signed32)ts - (signed32)tt;
    191      1.1  christos   return QH_CLAMP(t);
    192      1.1  christos }
    193      1.1  christos 
    194      1.1  christos static unsigned8
    195      1.1  christos SubOB(unsigned8 ts, unsigned8 tt)
    196      1.1  christos {
    197      1.1  christos   signed32 t;
    198      1.1  christos   t = (signed32)ts - (signed32)tt;
    199      1.1  christos   if (t < 0)
    200      1.1  christos     t = 0;
    201      1.1  christos   return (unsigned8)t;
    202      1.1  christos }
    203      1.1  christos 
    204      1.1  christos static signed16
    205      1.1  christos MinQH(signed16 ts, signed16 tt)
    206      1.1  christos {
    207      1.1  christos   return (ts < tt ? ts : tt);
    208      1.1  christos }
    209      1.1  christos 
    210      1.1  christos static unsigned8
    211      1.1  christos MinOB(unsigned8 ts, unsigned8 tt)
    212      1.1  christos {
    213      1.1  christos   return (ts < tt ? ts : tt);
    214      1.1  christos }
    215      1.1  christos 
    216      1.1  christos static signed16
    217      1.1  christos MaxQH(signed16 ts, signed16 tt)
    218      1.1  christos {
    219      1.1  christos   return (ts > tt ? ts : tt);
    220      1.1  christos }
    221      1.1  christos 
    222      1.1  christos static unsigned8
    223      1.1  christos MaxOB(unsigned8 ts, unsigned8 tt)
    224      1.1  christos {
    225      1.1  christos   return (ts > tt ? ts : tt);
    226      1.1  christos }
    227      1.1  christos 
    228      1.1  christos static signed16
    229      1.1  christos MulQH(signed16 ts, signed16 tt)
    230      1.1  christos {
    231      1.1  christos   signed32 t = (signed32)ts * (signed32)tt;
    232      1.1  christos   return QH_CLAMP(t);
    233      1.1  christos }
    234      1.1  christos 
    235      1.1  christos static unsigned8
    236      1.1  christos MulOB(unsigned8 ts, unsigned8 tt)
    237      1.1  christos {
    238      1.1  christos   unsigned32 t = (unsigned32)ts * (unsigned32)tt;
    239      1.1  christos   return OB_CLAMP(t);
    240      1.1  christos }
    241      1.1  christos 
    242      1.1  christos /* "msgn" and "sra" are defined only for QH format.  */
    243      1.1  christos 
    244      1.1  christos static signed16
    245      1.1  christos MsgnQH(signed16 ts, signed16 tt)
    246      1.1  christos {
    247      1.1  christos   signed16 t;
    248      1.1  christos   if (ts < 0)
    249      1.1  christos     t = (tt == QH_MIN ? QH_MAX : -tt);
    250      1.1  christos   else if (ts == 0)
    251      1.1  christos     t = 0;
    252      1.1  christos   else
    253      1.1  christos     t = tt;
    254      1.1  christos   return t;
    255      1.1  christos }
    256      1.1  christos 
    257      1.1  christos static signed16
    258      1.1  christos SRAQH(signed16 ts, signed16 tt)
    259      1.1  christos {
    260      1.1  christos   unsigned32 s = (unsigned32)tt & 0xF;
    261      1.1  christos   return (signed16)((signed32)ts >> s);
    262      1.1  christos }
    263      1.1  christos 
    264      1.1  christos 
    265      1.1  christos /* "pabsdiff" and "pavg" are defined only for OB format.  */
    266      1.1  christos 
    267      1.1  christos static unsigned8
    268      1.1  christos AbsDiffOB(unsigned8 ts, unsigned8 tt)
    269      1.1  christos {
    270      1.1  christos   return (ts >= tt ? ts - tt : tt - ts);
    271      1.1  christos }
    272      1.1  christos 
    273      1.1  christos static unsigned8
    274      1.1  christos AvgOB(unsigned8 ts, unsigned8 tt)
    275      1.1  christos {
    276      1.1  christos   return ((unsigned32)ts + (unsigned32)tt + 1) >> 1;
    277      1.1  christos }
    278      1.1  christos 
    279      1.1  christos 
    280      1.1  christos /* Dispatch tables for operations that update a CPR.  */
    281      1.1  christos 
    282      1.1  christos static const QH_FUNC qh_func[] = {
    283      1.1  christos   AndQH,  NorQH,  OrQH,   XorQH, SLLQH, SRLQH,
    284      1.1  christos   AddQH,  SubQH,  MinQH,  MaxQH,
    285      1.1  christos   MulQH,  MsgnQH, SRAQH,  NULL,  NULL
    286      1.1  christos };
    287      1.1  christos 
    288      1.1  christos static const OB_FUNC ob_func[] = {
    289      1.1  christos   AndOB,  NorOB,  OrOB,   XorOB, SLLOB, SRLOB,
    290      1.1  christos   AddOB,  SubOB,  MinOB,  MaxOB,
    291      1.1  christos   MulOB,  NULL,   NULL,   AbsDiffOB, AvgOB
    292      1.1  christos };
    293      1.1  christos 
    294      1.1  christos /* Auxiliary functions for CPR updates.  */
    295      1.1  christos 
    296      1.1  christos /* Vector mapping for QH format.  */
    297      1.1  christos static unsigned64
    298      1.1  christos qh_vector_op(unsigned64 v1, unsigned64 v2, QH_FUNC func)
    299      1.1  christos {
    300      1.1  christos   unsigned64 result = 0;
    301      1.1  christos   int  i;
    302      1.1  christos   signed16 h, h1, h2;
    303      1.1  christos 
    304      1.1  christos   for (i = 0; i < 64; i += 16)
    305      1.1  christos     {
    306      1.1  christos       h1 = (signed16)(v1 & 0xFFFF);  v1 >>= 16;
    307      1.1  christos       h2 = (signed16)(v2 & 0xFFFF);  v2 >>= 16;
    308      1.1  christos       h = (*func)(h1, h2);
    309      1.1  christos       result |= ((unsigned64)((unsigned16)h) << i);
    310      1.1  christos     }
    311      1.1  christos   return result;
    312      1.1  christos }
    313      1.1  christos 
    314      1.1  christos static unsigned64
    315      1.1  christos qh_map_op(unsigned64 v1, signed16 h2, QH_FUNC func)
    316      1.1  christos {
    317      1.1  christos   unsigned64 result = 0;
    318      1.1  christos   int  i;
    319      1.1  christos   signed16 h, h1;
    320      1.1  christos 
    321      1.1  christos   for (i = 0; i < 64; i += 16)
    322      1.1  christos     {
    323      1.1  christos       h1 = (signed16)(v1 & 0xFFFF);  v1 >>= 16;
    324      1.1  christos       h = (*func)(h1, h2);
    325      1.1  christos       result |= ((unsigned64)((unsigned16)h) << i);
    326      1.1  christos     }
    327      1.1  christos   return result;
    328      1.1  christos }
    329      1.1  christos 
    330      1.1  christos 
    331      1.1  christos /* Vector operations for OB format.  */
    332      1.1  christos 
    333      1.1  christos static unsigned64
    334      1.1  christos ob_vector_op(unsigned64 v1, unsigned64 v2, OB_FUNC func)
    335      1.1  christos {
    336      1.1  christos   unsigned64 result = 0;
    337      1.1  christos   int  i;
    338      1.1  christos   unsigned8 b, b1, b2;
    339      1.1  christos 
    340      1.1  christos   for (i = 0; i < 64; i += 8)
    341      1.1  christos     {
    342      1.1  christos       b1 = v1 & 0xFF;  v1 >>= 8;
    343      1.1  christos       b2 = v2 & 0xFF;  v2 >>= 8;
    344      1.1  christos       b = (*func)(b1, b2);
    345      1.1  christos       result |= ((unsigned64)b << i);
    346      1.1  christos     }
    347      1.1  christos   return result;
    348      1.1  christos }
    349      1.1  christos 
    350      1.1  christos static unsigned64
    351      1.1  christos ob_map_op(unsigned64 v1, unsigned8 b2, OB_FUNC func)
    352      1.1  christos {
    353      1.1  christos   unsigned64 result = 0;
    354      1.1  christos   int  i;
    355      1.1  christos   unsigned8 b, b1;
    356      1.1  christos 
    357      1.1  christos   for (i = 0; i < 64; i += 8)
    358      1.1  christos     {
    359      1.1  christos       b1 = v1 & 0xFF;  v1 >>= 8;
    360      1.1  christos       b = (*func)(b1, b2);
    361      1.1  christos       result |= ((unsigned64)b << i);
    362      1.1  christos     }
    363      1.1  christos   return result;
    364      1.1  christos }
    365      1.1  christos 
    366      1.1  christos 
    367      1.1  christos /* Primary entry for operations that update CPRs.  */
    368      1.1  christos unsigned64
    369      1.1  christos mdmx_cpr_op(sim_cpu *cpu,
    370      1.1  christos 	    address_word cia,
    371      1.1  christos 	    int op,
    372      1.1  christos 	    unsigned64 op1,
    373      1.1  christos 	    int vt,
    374      1.1  christos 	    MX_fmtsel fmtsel)
    375      1.1  christos {
    376      1.1  christos   unsigned64 op2;
    377      1.1  christos   unsigned64 result = 0;
    378      1.1  christos 
    379      1.1  christos   switch (MX_FMT (fmtsel))
    380      1.1  christos     {
    381      1.1  christos     case mdmx_qh:
    382      1.1  christos       switch (MX_VT (fmtsel))
    383      1.1  christos 	{
    384      1.1  christos 	case sel_elem:
    385      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
    386      1.1  christos 	  result = qh_map_op(op1, QH_ELEM(op2, fmtsel), qh_func[op]);
    387      1.1  christos 	  break;
    388      1.1  christos 	case sel_vect:
    389      1.1  christos 	  result = qh_vector_op(op1, ValueFPR(vt, fmt_mdmx), qh_func[op]);
    390      1.1  christos 	  break;
    391      1.1  christos 	case sel_imm:
    392      1.1  christos 	  result = qh_map_op(op1, vt, qh_func[op]);
    393      1.1  christos 	  break;
    394      1.1  christos 	}
    395      1.1  christos       break;
    396      1.1  christos     case mdmx_ob:
    397      1.1  christos       switch (MX_VT (fmtsel))
    398      1.1  christos 	{
    399      1.1  christos 	case sel_elem:
    400      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
    401      1.1  christos 	  result = ob_map_op(op1, OB_ELEM(op2, fmtsel), ob_func[op]);
    402      1.1  christos 	  break;
    403      1.1  christos 	case sel_vect:
    404      1.1  christos 	  result = ob_vector_op(op1, ValueFPR(vt, fmt_mdmx), ob_func[op]);
    405      1.1  christos 	  break;
    406      1.1  christos 	case sel_imm:
    407      1.1  christos 	  result = ob_map_op(op1, vt, ob_func[op]);
    408      1.1  christos 	  break;
    409      1.1  christos 	}
    410      1.1  christos       break;
    411      1.1  christos     default:
    412      1.1  christos       Unpredictable ();
    413      1.1  christos     }
    414      1.1  christos 
    415      1.1  christos   return result;
    416      1.1  christos }
    417      1.1  christos 
    418      1.1  christos 
    419      1.1  christos /* Operations that update CCs */
    420      1.1  christos 
    421      1.1  christos static void
    422      1.1  christos qh_vector_test(sim_cpu *cpu, unsigned64 v1, unsigned64 v2, int cond)
    423      1.1  christos {
    424      1.1  christos   int  i;
    425      1.1  christos   signed16 h1, h2;
    426      1.1  christos   int  boolean;
    427      1.1  christos 
    428      1.1  christos   for (i = 0; i < 4; i++)
    429      1.1  christos     {
    430      1.1  christos       h1 = (signed16)(v1 & 0xFFFF);  v1 >>= 16;
    431      1.1  christos       h2 = (signed16)(v2 & 0xFFFF);  v2 >>= 16;
    432      1.1  christos       boolean = ((cond & MX_C_EQ) && (h1 == h2)) ||
    433      1.1  christos 	((cond & MX_C_LT) && (h1 < h2));
    434      1.1  christos       SETFCC(i, boolean);
    435      1.1  christos     }
    436      1.1  christos }
    437      1.1  christos 
    438      1.1  christos static void
    439      1.1  christos qh_map_test(sim_cpu *cpu, unsigned64 v1, signed16 h2, int cond)
    440      1.1  christos {
    441      1.1  christos   int  i;
    442      1.1  christos   signed16 h1;
    443      1.1  christos   int  boolean;
    444      1.1  christos 
    445      1.1  christos   for (i = 0; i < 4; i++)
    446      1.1  christos     {
    447      1.1  christos       h1 = (signed16)(v1 & 0xFFFF);  v1 >>= 16;
    448      1.1  christos       boolean = ((cond & MX_C_EQ) && (h1 == h2)) ||
    449      1.1  christos 	((cond & MX_C_LT) && (h1 < h2));
    450      1.1  christos       SETFCC(i, boolean);
    451      1.1  christos     }
    452      1.1  christos }
    453      1.1  christos 
    454      1.1  christos static void
    455      1.1  christos ob_vector_test(sim_cpu *cpu, unsigned64 v1, unsigned64 v2, int cond)
    456      1.1  christos {
    457      1.1  christos   int  i;
    458      1.1  christos   unsigned8 b1, b2;
    459      1.1  christos   int  boolean;
    460      1.1  christos 
    461      1.1  christos   for (i = 0; i < 8; i++)
    462      1.1  christos     {
    463      1.1  christos       b1 = v1 & 0xFF;  v1 >>= 8;
    464      1.1  christos       b2 = v2 & 0xFF;  v2 >>= 8;
    465      1.1  christos       boolean = ((cond & MX_C_EQ) && (b1 == b2)) ||
    466      1.1  christos 	((cond & MX_C_LT) && (b1 < b2));
    467      1.1  christos       SETFCC(i, boolean);
    468      1.1  christos     }
    469      1.1  christos }
    470      1.1  christos 
    471      1.1  christos static void
    472      1.1  christos ob_map_test(sim_cpu *cpu, unsigned64 v1, unsigned8 b2, int cond)
    473      1.1  christos {
    474      1.1  christos   int  i;
    475      1.1  christos   unsigned8 b1;
    476      1.1  christos   int  boolean;
    477      1.1  christos 
    478      1.1  christos   for (i = 0; i < 8; i++)
    479      1.1  christos     {
    480      1.1  christos       b1 = (unsigned8)(v1 & 0xFF);  v1 >>= 8;
    481      1.1  christos       boolean = ((cond & MX_C_EQ) && (b1 == b2)) ||
    482      1.1  christos 	((cond & MX_C_LT) && (b1 < b2));
    483      1.1  christos       SETFCC(i, boolean);
    484      1.1  christos     }
    485      1.1  christos }
    486      1.1  christos 
    487      1.1  christos 
    488      1.1  christos void
    489      1.1  christos mdmx_cc_op(sim_cpu *cpu,
    490      1.1  christos 	   address_word cia,
    491      1.1  christos 	   int cond,
    492      1.1  christos 	   unsigned64 v1,
    493      1.1  christos 	   int vt,
    494      1.1  christos 	   MX_fmtsel fmtsel)
    495      1.1  christos {
    496      1.1  christos   unsigned64 op2;
    497      1.1  christos 
    498      1.1  christos   switch (MX_FMT (fmtsel))
    499      1.1  christos     {
    500      1.1  christos     case mdmx_qh:
    501      1.1  christos       switch (MX_VT (fmtsel))
    502      1.1  christos 	{
    503      1.1  christos 	case sel_elem:
    504      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
    505      1.1  christos 	  qh_map_test(cpu, v1, QH_ELEM(op2, fmtsel), cond);
    506      1.1  christos 	  break;
    507      1.1  christos 	case sel_vect:
    508      1.1  christos 	  qh_vector_test(cpu, v1, ValueFPR(vt, fmt_mdmx), cond);
    509      1.1  christos 	  break;
    510      1.1  christos 	case sel_imm:
    511      1.1  christos 	  qh_map_test(cpu, v1, vt, cond);
    512      1.1  christos 	  break;
    513      1.1  christos 	}
    514      1.1  christos       break;
    515      1.1  christos     case mdmx_ob:
    516      1.1  christos       switch (MX_VT (fmtsel))
    517      1.1  christos 	{
    518      1.1  christos 	case sel_elem:
    519      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
    520      1.1  christos 	  ob_map_test(cpu, v1, OB_ELEM(op2, fmtsel), cond);
    521      1.1  christos 	  break;
    522      1.1  christos 	case sel_vect:
    523      1.1  christos 	  ob_vector_test(cpu, v1, ValueFPR(vt, fmt_mdmx), cond);
    524      1.1  christos 	  break;
    525      1.1  christos 	case sel_imm:
    526      1.1  christos 	  ob_map_test(cpu, v1, vt, cond);
    527      1.1  christos 	  break;
    528      1.1  christos 	}
    529      1.1  christos       break;
    530      1.1  christos     default:
    531      1.1  christos       Unpredictable ();
    532      1.1  christos     }
    533      1.1  christos }
    534      1.1  christos 
    535      1.1  christos 
    536      1.1  christos /* Pick operations.  */
    537      1.1  christos 
    538      1.1  christos static unsigned64
    539      1.1  christos qh_vector_pick(sim_cpu *cpu, unsigned64 v1, unsigned64 v2, int tf)
    540      1.1  christos {
    541      1.1  christos   unsigned64 result = 0;
    542      1.1  christos   int  i, s;
    543      1.1  christos   unsigned16 h;
    544      1.1  christos 
    545      1.1  christos   s = 0;
    546      1.1  christos   for (i = 0; i < 4; i++)
    547      1.1  christos     {
    548      1.1  christos       h = ((GETFCC(i) == tf) ? (v1 & 0xFFFF) : (v2 & 0xFFFF));
    549      1.1  christos       v1 >>= 16;  v2 >>= 16;
    550      1.1  christos       result |= ((unsigned64)h << s);
    551      1.1  christos       s += 16;
    552      1.1  christos     }
    553      1.1  christos   return result;
    554      1.1  christos }
    555      1.1  christos 
    556      1.1  christos static unsigned64
    557      1.1  christos qh_map_pick(sim_cpu *cpu, unsigned64 v1, signed16 h2, int tf)
    558      1.1  christos {
    559      1.1  christos   unsigned64 result = 0;
    560      1.1  christos   int  i, s;
    561      1.1  christos   unsigned16 h;
    562      1.1  christos 
    563      1.1  christos   s = 0;
    564      1.1  christos   for (i = 0; i < 4; i++)
    565      1.1  christos     {
    566      1.1  christos       h = (GETFCC(i) == tf) ? (v1 & 0xFFFF) : (unsigned16)h2;
    567      1.1  christos       v1 >>= 16;
    568      1.1  christos       result |= ((unsigned64)h << s);
    569      1.1  christos       s += 16;
    570      1.1  christos     }
    571      1.1  christos   return result;
    572      1.1  christos }
    573      1.1  christos 
    574      1.1  christos static unsigned64
    575      1.1  christos ob_vector_pick(sim_cpu *cpu, unsigned64 v1, unsigned64 v2, int tf)
    576      1.1  christos {
    577      1.1  christos   unsigned64 result = 0;
    578      1.1  christos   int  i, s;
    579      1.1  christos   unsigned8 b;
    580      1.1  christos 
    581      1.1  christos   s = 0;
    582      1.1  christos   for (i = 0; i < 8; i++)
    583      1.1  christos     {
    584      1.1  christos       b = (GETFCC(i) == tf) ? (v1 & 0xFF) : (v2 & 0xFF);
    585      1.1  christos       v1 >>= 8;  v2 >>= 8;
    586      1.1  christos       result |= ((unsigned64)b << s);
    587      1.1  christos       s += 8;
    588      1.1  christos     }
    589      1.1  christos   return result;
    590      1.1  christos }
    591      1.1  christos 
    592      1.1  christos static unsigned64
    593      1.1  christos ob_map_pick(sim_cpu *cpu, unsigned64 v1, unsigned8 b2, int tf)
    594      1.1  christos {
    595      1.1  christos   unsigned64 result = 0;
    596      1.1  christos   int  i, s;
    597      1.1  christos   unsigned8 b;
    598      1.1  christos 
    599      1.1  christos   s = 0;
    600      1.1  christos   for (i = 0; i < 8; i++)
    601      1.1  christos     {
    602      1.1  christos       b = (GETFCC(i) == tf) ? (v1 & 0xFF) : b2;
    603      1.1  christos       v1 >>= 8;
    604      1.1  christos       result |= ((unsigned64)b << s);
    605      1.1  christos       s += 8;
    606      1.1  christos     }
    607      1.1  christos   return result;
    608      1.1  christos }
    609      1.1  christos 
    610      1.1  christos 
    611      1.1  christos unsigned64
    612      1.1  christos mdmx_pick_op(sim_cpu *cpu,
    613      1.1  christos 	     address_word cia,
    614      1.1  christos 	     int tf,
    615      1.1  christos 	     unsigned64 v1,
    616      1.1  christos 	     int vt,
    617      1.1  christos 	     MX_fmtsel fmtsel)
    618      1.1  christos {
    619      1.1  christos   unsigned64 result = 0;
    620      1.1  christos   unsigned64 op2;
    621      1.1  christos 
    622      1.1  christos   switch (MX_FMT (fmtsel))
    623      1.1  christos     {
    624      1.1  christos     case mdmx_qh:
    625      1.1  christos       switch (MX_VT (fmtsel))
    626      1.1  christos 	{
    627      1.1  christos 	case sel_elem:
    628      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
    629      1.1  christos 	  result = qh_map_pick(cpu, v1, QH_ELEM(op2, fmtsel), tf);
    630      1.1  christos 	  break;
    631      1.1  christos 	case sel_vect:
    632      1.1  christos 	  result = qh_vector_pick(cpu, v1, ValueFPR(vt, fmt_mdmx), tf);
    633      1.1  christos 	  break;
    634      1.1  christos 	case sel_imm:
    635      1.1  christos 	  result = qh_map_pick(cpu, v1, vt, tf);
    636      1.1  christos 	  break;
    637      1.1  christos 	}
    638      1.1  christos       break;
    639      1.1  christos     case mdmx_ob:
    640      1.1  christos       switch (MX_VT (fmtsel))
    641      1.1  christos 	{
    642      1.1  christos 	case sel_elem:
    643      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
    644      1.1  christos 	  result = ob_map_pick(cpu, v1, OB_ELEM(op2, fmtsel), tf);
    645      1.1  christos 	  break;
    646      1.1  christos 	case sel_vect:
    647      1.1  christos 	  result = ob_vector_pick(cpu, v1, ValueFPR(vt, fmt_mdmx), tf);
    648      1.1  christos 	  break;
    649      1.1  christos 	case sel_imm:
    650      1.1  christos 	  result = ob_map_pick(cpu, v1, vt, tf);
    651      1.1  christos 	  break;
    652      1.1  christos 	}
    653      1.1  christos       break;
    654      1.1  christos     default:
    655      1.1  christos       Unpredictable ();
    656      1.1  christos     }
    657      1.1  christos   return result;
    658      1.1  christos }
    659      1.1  christos 
    660      1.1  christos 
    661      1.1  christos /* Accumulators.  */
    662      1.1  christos 
    663      1.1  christos typedef void (*QH_ACC)(signed48 *a, signed16 ts, signed16 tt);
    664      1.1  christos 
    665      1.1  christos static void
    666      1.1  christos AccAddAQH(signed48 *a, signed16 ts, signed16 tt)
    667      1.1  christos {
    668      1.1  christos   *a += (signed48)ts + (signed48)tt;
    669      1.1  christos }
    670      1.1  christos 
    671      1.1  christos static void
    672      1.1  christos AccAddLQH(signed48 *a, signed16 ts, signed16 tt)
    673      1.1  christos {
    674      1.1  christos   *a = (signed48)ts + (signed48)tt;
    675      1.1  christos }
    676      1.1  christos 
    677      1.1  christos static void
    678      1.1  christos AccMulAQH(signed48 *a, signed16 ts, signed16 tt)
    679      1.1  christos {
    680      1.1  christos   *a += (signed48)ts * (signed48)tt;
    681      1.1  christos }
    682      1.1  christos 
    683      1.1  christos static void
    684      1.1  christos AccMulLQH(signed48 *a, signed16 ts, signed16 tt)
    685      1.1  christos {
    686      1.1  christos   *a = (signed48)ts * (signed48)tt;
    687      1.1  christos }
    688      1.1  christos 
    689      1.1  christos static void
    690      1.1  christos SubMulAQH(signed48 *a, signed16 ts, signed16 tt)
    691      1.1  christos {
    692      1.1  christos   *a -= (signed48)ts * (signed48)tt;
    693      1.1  christos }
    694      1.1  christos 
    695      1.1  christos static void
    696      1.1  christos SubMulLQH(signed48 *a, signed16 ts, signed16 tt)
    697      1.1  christos {
    698      1.1  christos   *a = -((signed48)ts * (signed48)tt);
    699      1.1  christos }
    700      1.1  christos 
    701      1.1  christos static void
    702      1.1  christos AccSubAQH(signed48 *a, signed16 ts, signed16 tt)
    703      1.1  christos {
    704      1.1  christos   *a += (signed48)ts - (signed48)tt;
    705      1.1  christos }
    706      1.1  christos 
    707      1.1  christos static void
    708      1.1  christos AccSubLQH(signed48 *a, signed16 ts, signed16 tt)
    709      1.1  christos {
    710      1.1  christos   *a =  (signed48)ts - (signed48)tt;
    711      1.1  christos }
    712      1.1  christos 
    713      1.1  christos 
    714      1.1  christos typedef void (*OB_ACC)(signed24 *acc, unsigned8 ts, unsigned8 tt);
    715      1.1  christos 
    716      1.1  christos static void
    717      1.1  christos AccAddAOB(signed24 *a, unsigned8 ts, unsigned8 tt)
    718      1.1  christos {
    719      1.1  christos   *a += (signed24)ts + (signed24)tt;
    720      1.1  christos }
    721      1.1  christos 
    722      1.1  christos static void
    723      1.1  christos AccAddLOB(signed24 *a, unsigned8 ts, unsigned8 tt)
    724      1.1  christos {
    725      1.1  christos   *a = (signed24)ts + (signed24)tt;
    726      1.1  christos }
    727      1.1  christos 
    728      1.1  christos static void
    729      1.1  christos AccMulAOB(signed24 *a, unsigned8 ts, unsigned8 tt)
    730      1.1  christos {
    731      1.1  christos   *a += (signed24)ts * (signed24)tt;
    732      1.1  christos }
    733      1.1  christos 
    734      1.1  christos static void
    735      1.1  christos AccMulLOB(signed24 *a, unsigned8 ts, unsigned8 tt)
    736      1.1  christos {
    737      1.1  christos   *a = (signed24)ts * (signed24)tt;
    738      1.1  christos }
    739      1.1  christos 
    740      1.1  christos static void
    741      1.1  christos SubMulAOB(signed24 *a, unsigned8 ts, unsigned8 tt)
    742      1.1  christos {
    743      1.1  christos   *a -= (signed24)ts * (signed24)tt;
    744      1.1  christos }
    745      1.1  christos 
    746      1.1  christos static void
    747      1.1  christos SubMulLOB(signed24 *a, unsigned8 ts, unsigned8 tt)
    748      1.1  christos {
    749      1.1  christos   *a = -((signed24)ts * (signed24)tt);
    750      1.1  christos }
    751      1.1  christos 
    752      1.1  christos static void
    753      1.1  christos AccSubAOB(signed24 *a, unsigned8 ts, unsigned8 tt)
    754      1.1  christos {
    755      1.1  christos   *a += (signed24)ts - (signed24)tt;
    756      1.1  christos }
    757      1.1  christos 
    758      1.1  christos static void
    759      1.1  christos AccSubLOB(signed24 *a, unsigned8 ts, unsigned8 tt)
    760      1.1  christos {
    761      1.1  christos   *a = (signed24)ts - (signed24)tt;
    762      1.1  christos }
    763      1.1  christos 
    764      1.1  christos static void
    765      1.1  christos AccAbsDiffOB(signed24 *a, unsigned8 ts, unsigned8 tt)
    766      1.1  christos {
    767      1.1  christos   unsigned8 t = (ts >= tt ? ts - tt : tt - ts);
    768      1.1  christos   *a += (signed24)t;
    769      1.1  christos }
    770      1.1  christos 
    771      1.1  christos 
    772      1.1  christos /* Dispatch tables for operations that update a CPR.  */
    773      1.1  christos 
    774      1.1  christos static const QH_ACC qh_acc[] = {
    775      1.1  christos   AccAddAQH, AccAddAQH, AccMulAQH, AccMulLQH,
    776      1.1  christos   SubMulAQH, SubMulLQH, AccSubAQH, AccSubLQH,
    777      1.1  christos   NULL
    778      1.1  christos };
    779      1.1  christos 
    780      1.1  christos static const OB_ACC ob_acc[] = {
    781      1.1  christos   AccAddAOB, AccAddLOB, AccMulAOB, AccMulLOB,
    782      1.1  christos   SubMulAOB, SubMulLOB, AccSubAOB, AccSubLOB,
    783      1.1  christos   AccAbsDiffOB
    784      1.1  christos };
    785      1.1  christos 
    786      1.1  christos 
    787      1.1  christos static void
    788      1.1  christos qh_vector_acc(signed48 a[], unsigned64 v1, unsigned64 v2, QH_ACC acc)
    789      1.1  christos {
    790      1.1  christos   int  i;
    791      1.1  christos   signed16 h1, h2;
    792      1.1  christos 
    793      1.1  christos   for (i = 0; i < 4; i++)
    794      1.1  christos     {
    795      1.1  christos       h1 = (signed16)(v1 & 0xFFFF);  v1 >>= 16;
    796      1.1  christos       h2 = (signed16)(v2 & 0xFFFF);  v2 >>= 16;
    797      1.1  christos       (*acc)(&a[i], h1, h2);
    798      1.1  christos     }
    799      1.1  christos }
    800      1.1  christos 
    801      1.1  christos static void
    802      1.1  christos qh_map_acc(signed48 a[], unsigned64 v1, signed16 h2, QH_ACC acc)
    803      1.1  christos {
    804      1.1  christos   int  i;
    805      1.1  christos   signed16 h1;
    806      1.1  christos 
    807      1.1  christos   for (i = 0; i < 4; i++)
    808      1.1  christos     {
    809      1.1  christos       h1 = (signed16)(v1 & 0xFFFF);  v1 >>= 16;
    810      1.1  christos       (*acc)(&a[i], h1, h2);
    811      1.1  christos     }
    812      1.1  christos }
    813      1.1  christos 
    814      1.1  christos static void
    815      1.1  christos ob_vector_acc(signed24 a[], unsigned64 v1, unsigned64 v2, OB_ACC acc)
    816      1.1  christos {
    817      1.1  christos   int  i;
    818      1.1  christos   unsigned8  b1, b2;
    819      1.1  christos 
    820      1.1  christos   for (i = 0; i < 8; i++)
    821      1.1  christos     {
    822      1.1  christos       b1 = v1 & 0xFF;  v1 >>= 8;
    823      1.1  christos       b2 = v2 & 0xFF;  v2 >>= 8;
    824      1.1  christos       (*acc)(&a[i], b1, b2);
    825      1.1  christos     }
    826      1.1  christos }
    827      1.1  christos 
    828      1.1  christos static void
    829      1.1  christos ob_map_acc(signed24 a[], unsigned64 v1, unsigned8 b2, OB_ACC acc)
    830      1.1  christos {
    831      1.1  christos   int  i;
    832      1.1  christos   unsigned8 b1;
    833      1.1  christos 
    834      1.1  christos   for (i = 0; i < 8; i++)
    835      1.1  christos     {
    836      1.1  christos       b1 = v1 & 0xFF;  v1 >>= 8;
    837      1.1  christos       (*acc)(&a[i], b1, b2);
    838      1.1  christos     }
    839      1.1  christos }
    840      1.1  christos 
    841      1.1  christos 
    842      1.1  christos /* Primary entry for operations that accumulate */
    843      1.1  christos void
    844      1.1  christos mdmx_acc_op(sim_cpu *cpu,
    845      1.1  christos 	    address_word cia,
    846      1.1  christos 	    int op,
    847      1.1  christos 	    unsigned64 op1,
    848      1.1  christos 	    int vt,
    849      1.1  christos 	    MX_fmtsel fmtsel)
    850      1.1  christos {
    851      1.1  christos   unsigned64 op2;
    852      1.1  christos 
    853      1.1  christos   switch (MX_FMT (fmtsel))
    854      1.1  christos     {
    855      1.1  christos     case mdmx_qh:
    856      1.1  christos       switch (MX_VT (fmtsel))
    857      1.1  christos 	{
    858      1.1  christos 	case sel_elem:
    859      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
    860      1.1  christos 	  qh_map_acc(ACC.qh, op1, QH_ELEM(op2, fmtsel), qh_acc[op]);
    861      1.1  christos 	  break;
    862      1.1  christos 	case sel_vect:
    863      1.1  christos 	  qh_vector_acc(ACC.qh, op1, ValueFPR(vt, fmt_mdmx), qh_acc[op]);
    864      1.1  christos 	  break;
    865      1.1  christos 	case sel_imm:
    866      1.1  christos 	  qh_map_acc(ACC.qh, op1, vt, qh_acc[op]);
    867      1.1  christos 	  break;
    868      1.1  christos 	}
    869      1.1  christos       break;
    870      1.1  christos     case mdmx_ob:
    871      1.1  christos       switch (MX_VT (fmtsel))
    872      1.1  christos 	{
    873      1.1  christos 	case sel_elem:
    874      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
    875      1.1  christos 	  ob_map_acc(ACC.ob, op1, OB_ELEM(op2, fmtsel), ob_acc[op]);
    876      1.1  christos 	  break;
    877      1.1  christos 	case sel_vect:
    878      1.1  christos 	  ob_vector_acc(ACC.ob, op1, ValueFPR(vt, fmt_mdmx), ob_acc[op]);
    879      1.1  christos 	  break;
    880      1.1  christos 	case sel_imm:
    881      1.1  christos 	  ob_map_acc(ACC.ob, op1, vt, ob_acc[op]);
    882      1.1  christos 	  break;
    883      1.1  christos 	}
    884      1.1  christos       break;
    885      1.1  christos     default:
    886      1.1  christos       Unpredictable ();
    887      1.1  christos     }
    888      1.1  christos }
    889      1.1  christos 
    890      1.1  christos 
    891      1.1  christos /* Reading and writing accumulator (no conversion).  */
    892      1.1  christos 
    893      1.1  christos unsigned64
    894      1.1  christos mdmx_rac_op(sim_cpu *cpu,
    895      1.1  christos 	    address_word cia,
    896      1.1  christos 	    int op,
    897      1.1  christos 	    int fmt)
    898      1.1  christos {
    899      1.1  christos   unsigned64    result;
    900      1.1  christos   unsigned int  shift;
    901      1.1  christos   int           i;
    902      1.1  christos 
    903      1.1  christos   shift = op;          /* L = 00, M = 01, H = 10.  */
    904      1.1  christos   result = 0;
    905      1.1  christos 
    906      1.1  christos   switch (fmt)
    907      1.1  christos     {
    908      1.1  christos     case MX_FMT_QH:
    909      1.1  christos       shift <<= 4;              /* 16 bits per element.  */
    910      1.1  christos       for (i = 3; i >= 0; --i)
    911      1.1  christos 	{
    912      1.1  christos 	  result <<= 16;
    913      1.1  christos 	  result |= ((ACC.qh[i] >> shift) & 0xFFFF);
    914      1.1  christos 	}
    915      1.1  christos       break;
    916      1.1  christos     case MX_FMT_OB:
    917      1.1  christos       shift <<= 3;              /*  8 bits per element.  */
    918      1.1  christos       for (i = 7; i >= 0; --i)
    919      1.1  christos 	{
    920      1.1  christos 	  result <<= 8;
    921      1.1  christos 	  result |= ((ACC.ob[i] >> shift) & 0xFF);
    922      1.1  christos 	}
    923      1.1  christos       break;
    924      1.1  christos     default:
    925      1.1  christos       Unpredictable ();
    926      1.1  christos     }
    927      1.1  christos   return result;
    928      1.1  christos }
    929      1.1  christos 
    930      1.1  christos void
    931      1.1  christos mdmx_wacl(sim_cpu *cpu,
    932      1.1  christos 	  address_word cia,
    933      1.1  christos 	  int fmt,
    934      1.1  christos 	  unsigned64 vs,
    935      1.1  christos 	  unsigned64 vt)
    936      1.1  christos {
    937      1.1  christos   int           i;
    938      1.1  christos 
    939      1.1  christos   switch (fmt)
    940      1.1  christos     {
    941      1.1  christos     case MX_FMT_QH:
    942      1.1  christos       for (i = 0; i < 4; i++)
    943      1.1  christos 	{
    944      1.1  christos 	  signed32  s = (signed16)(vs & 0xFFFF);
    945      1.1  christos 	  ACC.qh[i] = ((signed48)s << 16) | (vt & 0xFFFF);
    946      1.1  christos 	  vs >>= 16;  vt >>= 16;
    947      1.1  christos 	}
    948      1.1  christos       break;
    949      1.1  christos     case MX_FMT_OB:
    950      1.1  christos       for (i = 0; i < 8; i++)
    951      1.1  christos 	{
    952      1.1  christos 	  signed16  s = (signed8)(vs & 0xFF);
    953      1.1  christos 	  ACC.ob[i] = ((signed24)s << 8) | (vt & 0xFF);
    954      1.1  christos 	  vs >>= 8;   vt >>= 8;
    955      1.1  christos 	}
    956      1.1  christos       break;
    957      1.1  christos     default:
    958      1.1  christos       Unpredictable ();
    959      1.1  christos     }
    960      1.1  christos }
    961      1.1  christos 
    962      1.1  christos void
    963      1.1  christos mdmx_wach(sim_cpu *cpu,
    964      1.1  christos 	  address_word cia,
    965      1.1  christos 	  int fmt,
    966      1.1  christos 	  unsigned64 vs)
    967      1.1  christos {
    968      1.1  christos   int           i;
    969      1.1  christos 
    970      1.1  christos   switch (fmt)
    971      1.1  christos     {
    972      1.1  christos     case MX_FMT_QH:
    973      1.1  christos       for (i = 0; i < 4; i++)
    974      1.1  christos 	{
    975      1.1  christos 	  signed32  s = (signed16)(vs & 0xFFFF);
    976      1.1  christos 	  ACC.qh[i] &= ~((signed48)0xFFFF << 32);
    977      1.1  christos 	  ACC.qh[i] |=  ((signed48)s << 32);
    978      1.1  christos 	  vs >>= 16;
    979      1.1  christos 	}
    980      1.1  christos       break;
    981      1.1  christos     case MX_FMT_OB:
    982      1.1  christos       for (i = 0; i < 8; i++)
    983      1.1  christos 	{
    984      1.1  christos 	  ACC.ob[i] &= ~((signed24)0xFF << 16);
    985      1.1  christos 	  ACC.ob[i] |=  ((signed24)(vs & 0xFF) << 16);
    986      1.1  christos 	  vs >>= 8;
    987      1.1  christos 	}
    988      1.1  christos       break;
    989      1.1  christos     default:
    990      1.1  christos       Unpredictable ();
    991      1.1  christos     }
    992      1.1  christos }
    993      1.1  christos 
    994      1.1  christos 
    995      1.1  christos /* Reading and writing accumulator (rounding conversions).
    996      1.1  christos    Enumerating function guarantees s >= 0 for QH ops.  */
    997      1.1  christos 
    998      1.1  christos typedef signed16 (*QH_ROUND)(signed48 a, signed16 s);
    999      1.1  christos 
   1000      1.1  christos #define QH_BIT(n)  ((unsigned48)1 << (n))
   1001      1.1  christos #define QH_ONES(n) (((unsigned48)1 << (n))-1)
   1002      1.1  christos 
   1003      1.1  christos static signed16
   1004      1.1  christos RNASQH(signed48 a, signed16 s)
   1005      1.1  christos {
   1006      1.1  christos   signed48 t;
   1007      1.1  christos   signed16 result = 0;
   1008      1.1  christos 
   1009      1.1  christos   if (s > 48)
   1010      1.1  christos     result = 0;
   1011      1.1  christos   else
   1012      1.1  christos     {
   1013      1.1  christos       t = (a >> s);
   1014      1.1  christos       if ((a & QH_BIT(47)) == 0)
   1015      1.1  christos 	{
   1016      1.1  christos 	  if (s > 0 && ((a >> (s-1)) & 1) == 1)
   1017      1.1  christos 	    t++;
   1018      1.1  christos 	  if (t > QH_MAX)
   1019      1.1  christos 	    t = QH_MAX;
   1020      1.1  christos 	}
   1021      1.1  christos       else
   1022      1.1  christos 	{
   1023      1.1  christos 	  if (s > 0 && ((a >> (s-1)) & 1) == 1)
   1024      1.1  christos 	    {
   1025      1.1  christos 	      if (s > 1 && ((unsigned48)a & QH_ONES(s-1)) != 0)
   1026      1.1  christos 		t++;
   1027      1.1  christos 	    }
   1028      1.1  christos 	  if (t < QH_MIN)
   1029      1.1  christos 	    t = QH_MIN;
   1030      1.1  christos 	}
   1031      1.1  christos       result = (signed16)t;
   1032      1.1  christos     }
   1033      1.1  christos   return result;
   1034      1.1  christos }
   1035      1.1  christos 
   1036      1.1  christos static signed16
   1037      1.1  christos RNAUQH(signed48 a, signed16 s)
   1038      1.1  christos {
   1039      1.1  christos   unsigned48 t;
   1040      1.1  christos   signed16 result;
   1041      1.1  christos 
   1042      1.1  christos   if (s > 48)
   1043      1.1  christos     result = 0;
   1044      1.1  christos   else if (s == 48)
   1045      1.1  christos     result = ((unsigned48)a & MASK48) >> 47;
   1046      1.1  christos   else
   1047      1.1  christos     {
   1048      1.1  christos       t = ((unsigned48)a & MASK48) >> s;
   1049      1.1  christos       if (s > 0 && ((a >> (s-1)) & 1) == 1)
   1050      1.1  christos 	t++;
   1051      1.1  christos       if (t > 0xFFFF)
   1052      1.1  christos 	t = 0xFFFF;
   1053      1.1  christos       result = (signed16)t;
   1054      1.1  christos     }
   1055      1.1  christos   return result;
   1056      1.1  christos }
   1057      1.1  christos 
   1058      1.1  christos static signed16
   1059      1.1  christos RNESQH(signed48 a, signed16 s)
   1060      1.1  christos {
   1061      1.1  christos   signed48 t;
   1062      1.1  christos   signed16 result = 0;
   1063      1.1  christos 
   1064      1.1  christos   if (s > 47)
   1065      1.1  christos     result = 0;
   1066      1.1  christos   else
   1067      1.1  christos     {
   1068      1.1  christos       t = (a >> s);
   1069      1.1  christos       if (s > 0 && ((a >> (s-1)) & 1) == 1)
   1070      1.1  christos 	{
   1071      1.1  christos 	  if (s == 1 || (a & QH_ONES(s-1)) == 0)
   1072      1.1  christos 	    t += t & 1;
   1073      1.1  christos 	  else
   1074      1.1  christos 	    t += 1;
   1075      1.1  christos 	}
   1076      1.1  christos       if ((a & QH_BIT(47)) == 0)
   1077      1.1  christos 	{
   1078      1.1  christos 	  if (t > QH_MAX)
   1079      1.1  christos 	    t = QH_MAX;
   1080      1.1  christos 	}
   1081      1.1  christos       else
   1082      1.1  christos 	{
   1083      1.1  christos 	  if (t < QH_MIN)
   1084      1.1  christos 	    t = QH_MIN;
   1085      1.1  christos 	}
   1086      1.1  christos       result = (signed16)t;
   1087      1.1  christos     }
   1088      1.1  christos   return result;
   1089      1.1  christos }
   1090      1.1  christos 
   1091      1.1  christos static signed16
   1092      1.1  christos RNEUQH(signed48 a, signed16 s)
   1093      1.1  christos {
   1094      1.1  christos   unsigned48 t;
   1095      1.1  christos   signed16 result;
   1096      1.1  christos 
   1097      1.1  christos   if (s > 48)
   1098      1.1  christos     result = 0;
   1099      1.1  christos   else if (s == 48)
   1100      1.1  christos     result = ((unsigned48)a > QH_BIT(47) ? 1 : 0);
   1101      1.1  christos   else
   1102      1.1  christos     {
   1103      1.1  christos       t = ((unsigned48)a & MASK48) >> s;
   1104      1.1  christos       if (s > 0 && ((a >> (s-1)) & 1) == 1)
   1105      1.1  christos 	{
   1106      1.1  christos 	  if (s > 1 && (a & QH_ONES(s-1)) != 0)
   1107      1.1  christos 	    t++;
   1108      1.1  christos 	  else
   1109      1.1  christos 	    t += t & 1;
   1110      1.1  christos 	}
   1111      1.1  christos       if (t > 0xFFFF)
   1112      1.1  christos 	t = 0xFFFF;
   1113      1.1  christos       result = (signed16)t;
   1114      1.1  christos     }
   1115      1.1  christos   return result;
   1116      1.1  christos }
   1117      1.1  christos 
   1118      1.1  christos static signed16
   1119      1.1  christos RZSQH(signed48 a, signed16 s)
   1120      1.1  christos {
   1121      1.1  christos   signed48 t;
   1122      1.1  christos   signed16 result = 0;
   1123      1.1  christos 
   1124      1.1  christos   if (s > 47)
   1125      1.1  christos     result = 0;
   1126      1.1  christos   else
   1127      1.1  christos     {
   1128      1.1  christos       t = (a >> s);
   1129      1.1  christos       if ((a & QH_BIT(47)) == 0)
   1130      1.1  christos 	{
   1131      1.1  christos 	  if (t > QH_MAX)
   1132      1.1  christos 	    t = QH_MAX;
   1133      1.1  christos 	}
   1134      1.1  christos       else
   1135      1.1  christos 	{
   1136      1.1  christos 	  if (t < QH_MIN)
   1137      1.1  christos 	    t = QH_MIN;
   1138      1.1  christos 	}
   1139      1.1  christos       result = (signed16)t;
   1140      1.1  christos     }
   1141      1.1  christos   return result;
   1142      1.1  christos }
   1143      1.1  christos 
   1144      1.1  christos static signed16
   1145      1.1  christos RZUQH(signed48 a, signed16 s)
   1146      1.1  christos {
   1147      1.1  christos   unsigned48 t;
   1148      1.1  christos   signed16 result = 0;
   1149      1.1  christos 
   1150      1.1  christos   if (s > 48)
   1151      1.1  christos     result = 0;
   1152      1.1  christos   else if (s == 48)
   1153      1.1  christos     result = ((unsigned48)a > QH_BIT(47) ? 1 : 0);
   1154      1.1  christos   else
   1155      1.1  christos     {
   1156      1.1  christos       t = ((unsigned48)a & MASK48) >> s;
   1157      1.1  christos       if (t > 0xFFFF)
   1158      1.1  christos 	t = 0xFFFF;
   1159      1.1  christos       result = (signed16)t;
   1160      1.1  christos     }
   1161      1.1  christos   return result;
   1162      1.1  christos }
   1163      1.1  christos 
   1164      1.1  christos 
   1165      1.1  christos typedef unsigned8 (*OB_ROUND)(signed24 a, unsigned8 s);
   1166      1.1  christos 
   1167      1.1  christos #define OB_BIT(n)  ((unsigned24)1 << (n))
   1168      1.1  christos #define OB_ONES(n) (((unsigned24)1 << (n))-1)
   1169      1.1  christos 
   1170      1.1  christos static unsigned8
   1171      1.1  christos RNAUOB(signed24 a, unsigned8 s)
   1172      1.1  christos {
   1173      1.1  christos   unsigned8 result;
   1174      1.1  christos   unsigned24 t;
   1175      1.1  christos 
   1176      1.1  christos   if (s > 24)
   1177      1.1  christos     result = 0;
   1178      1.1  christos   else if (s == 24)
   1179      1.1  christos     result = ((unsigned24)a & MASK24) >> 23;
   1180      1.1  christos   else
   1181      1.1  christos     {
   1182      1.1  christos       t = ((unsigned24)a & MASK24) >> s;
   1183      1.1  christos       if (s > 0 && ((a >> (s-1)) & 1) == 1)
   1184      1.1  christos 	t ++;
   1185      1.1  christos       result = OB_CLAMP(t);
   1186      1.1  christos     }
   1187      1.1  christos   return result;
   1188      1.1  christos }
   1189      1.1  christos 
   1190      1.1  christos static unsigned8
   1191      1.1  christos RNEUOB(signed24 a, unsigned8 s)
   1192      1.1  christos {
   1193      1.1  christos   unsigned8 result;
   1194      1.1  christos   unsigned24 t;
   1195      1.1  christos 
   1196      1.1  christos   if (s > 24)
   1197      1.1  christos     result = 0;
   1198      1.1  christos   else if (s == 24)
   1199      1.1  christos     result = (((unsigned24)a & MASK24) > OB_BIT(23) ? 1 : 0);
   1200      1.1  christos   else
   1201      1.1  christos     {
   1202      1.1  christos       t = ((unsigned24)a & MASK24) >> s;
   1203      1.1  christos       if (s > 0 && ((a >> (s-1)) & 1) == 1)
   1204      1.1  christos 	{
   1205      1.1  christos 	  if (s > 1 && (a & OB_ONES(s-1)) != 0)
   1206      1.1  christos 	    t++;
   1207      1.1  christos 	  else
   1208      1.1  christos 	    t += t & 1;
   1209      1.1  christos 	}
   1210      1.1  christos       result = OB_CLAMP(t);
   1211      1.1  christos     }
   1212      1.1  christos   return result;
   1213      1.1  christos }
   1214      1.1  christos 
   1215      1.1  christos static unsigned8
   1216      1.1  christos RZUOB(signed24 a, unsigned8 s)
   1217      1.1  christos {
   1218      1.1  christos   unsigned8 result;
   1219      1.1  christos   unsigned24 t;
   1220      1.1  christos 
   1221      1.1  christos   if (s >= 24)
   1222      1.1  christos     result = 0;
   1223      1.1  christos   else
   1224      1.1  christos     {
   1225      1.1  christos       t = ((unsigned24)a & MASK24) >> s;
   1226      1.1  christos       result = OB_CLAMP(t);
   1227      1.1  christos     }
   1228      1.1  christos   return result;
   1229      1.1  christos }
   1230      1.1  christos 
   1231      1.1  christos 
   1232      1.1  christos static const QH_ROUND qh_round[] = {
   1233      1.1  christos   RNASQH, RNAUQH, RNESQH, RNEUQH, RZSQH,  RZUQH
   1234      1.1  christos };
   1235      1.1  christos 
   1236      1.1  christos static const OB_ROUND ob_round[] = {
   1237      1.1  christos   NULL,   RNAUOB, NULL,   RNEUOB, NULL,   RZUOB
   1238      1.1  christos };
   1239      1.1  christos 
   1240      1.1  christos 
   1241      1.1  christos static unsigned64
   1242      1.1  christos qh_vector_round(sim_cpu *cpu, address_word cia, unsigned64 v2, QH_ROUND round)
   1243      1.1  christos {
   1244      1.1  christos   unsigned64 result = 0;
   1245      1.1  christos   int  i, s;
   1246      1.1  christos   signed16 h, h2;
   1247      1.1  christos 
   1248      1.1  christos   s = 0;
   1249      1.1  christos   for (i = 0; i < 4; i++)
   1250      1.1  christos     {
   1251      1.1  christos       h2 = (signed16)(v2 & 0xFFFF);
   1252      1.1  christos       if (h2 >= 0)
   1253      1.1  christos 	h = (*round)(ACC.qh[i], h2);
   1254      1.1  christos       else
   1255      1.1  christos 	{
   1256      1.1  christos 	  UnpredictableResult ();
   1257      1.1  christos 	  h = 0xdead;
   1258      1.1  christos 	}
   1259      1.1  christos       v2 >>= 16;
   1260      1.1  christos       result |= ((unsigned64)((unsigned16)h) << s);
   1261      1.1  christos       s += 16;
   1262      1.1  christos     }
   1263      1.1  christos   return result;
   1264      1.1  christos }
   1265      1.1  christos 
   1266      1.1  christos static unsigned64
   1267      1.1  christos qh_map_round(sim_cpu *cpu, address_word cia, signed16 h2, QH_ROUND round)
   1268      1.1  christos {
   1269      1.1  christos   unsigned64 result = 0;
   1270      1.1  christos   int  i, s;
   1271      1.1  christos   signed16  h;
   1272      1.1  christos 
   1273      1.1  christos   s = 0;
   1274      1.1  christos   for (i = 0; i < 4; i++)
   1275      1.1  christos     {
   1276      1.1  christos       if (h2 >= 0)
   1277      1.1  christos 	h = (*round)(ACC.qh[i], h2);
   1278      1.1  christos       else
   1279      1.1  christos 	{
   1280      1.1  christos 	  UnpredictableResult ();
   1281      1.1  christos 	  h = 0xdead;
   1282      1.1  christos 	}
   1283      1.1  christos       result |= ((unsigned64)((unsigned16)h) << s);
   1284      1.1  christos       s += 16;
   1285      1.1  christos     }
   1286      1.1  christos   return result;
   1287      1.1  christos }
   1288      1.1  christos 
   1289      1.1  christos static unsigned64
   1290      1.1  christos ob_vector_round(sim_cpu *cpu, address_word cia, unsigned64 v2, OB_ROUND round)
   1291      1.1  christos {
   1292      1.1  christos   unsigned64 result = 0;
   1293      1.1  christos   int  i, s;
   1294      1.1  christos   unsigned8 b, b2;
   1295      1.1  christos 
   1296      1.1  christos   s = 0;
   1297      1.1  christos   for (i = 0; i < 8; i++)
   1298      1.1  christos     {
   1299      1.1  christos       b2 = v2 & 0xFF;  v2 >>= 8;
   1300      1.1  christos       b = (*round)(ACC.ob[i], b2);
   1301      1.1  christos       result |= ((unsigned64)b << s);
   1302      1.1  christos       s += 8;
   1303      1.1  christos     }
   1304      1.1  christos   return result;
   1305      1.1  christos }
   1306      1.1  christos 
   1307      1.1  christos static unsigned64
   1308      1.1  christos ob_map_round(sim_cpu *cpu, address_word cia, unsigned8 b2, OB_ROUND round)
   1309      1.1  christos {
   1310      1.1  christos   unsigned64 result = 0;
   1311      1.1  christos   int  i, s;
   1312      1.1  christos   unsigned8 b;
   1313      1.1  christos 
   1314      1.1  christos   s = 0;
   1315      1.1  christos   for (i = 0; i < 8; i++)
   1316      1.1  christos     {
   1317      1.1  christos       b = (*round)(ACC.ob[i], b2);
   1318      1.1  christos       result |= ((unsigned64)b << s);
   1319      1.1  christos       s += 8;
   1320      1.1  christos     }
   1321      1.1  christos   return result;
   1322      1.1  christos }
   1323      1.1  christos 
   1324      1.1  christos 
   1325      1.1  christos unsigned64
   1326      1.1  christos mdmx_round_op(sim_cpu *cpu,
   1327      1.1  christos 	      address_word cia,
   1328      1.1  christos 	      int rm,
   1329      1.1  christos 	      int vt,
   1330      1.1  christos 	      MX_fmtsel fmtsel)
   1331      1.1  christos {
   1332      1.1  christos   unsigned64 op2;
   1333      1.1  christos   unsigned64 result = 0;
   1334      1.1  christos 
   1335      1.1  christos   switch (MX_FMT (fmtsel))
   1336      1.1  christos     {
   1337      1.1  christos     case mdmx_qh:
   1338      1.1  christos       switch (MX_VT (fmtsel))
   1339      1.1  christos 	{
   1340      1.1  christos 	case sel_elem:
   1341      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
   1342      1.1  christos 	  result = qh_map_round(cpu, cia, QH_ELEM(op2, fmtsel), qh_round[rm]);
   1343      1.1  christos 	  break;
   1344      1.1  christos 	case sel_vect:
   1345      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
   1346      1.1  christos 	  result = qh_vector_round(cpu, cia, op2, qh_round[rm]);
   1347      1.1  christos 	  break;
   1348      1.1  christos 	case sel_imm:
   1349      1.1  christos 	  result = qh_map_round(cpu, cia, vt, qh_round[rm]);
   1350      1.1  christos 	  break;
   1351      1.1  christos 	}
   1352      1.1  christos       break;
   1353      1.1  christos     case mdmx_ob:
   1354      1.1  christos       switch (MX_VT (fmtsel))
   1355      1.1  christos 	{
   1356      1.1  christos 	case sel_elem:
   1357      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
   1358      1.1  christos 	  result = ob_map_round(cpu, cia, OB_ELEM(op2, fmtsel), ob_round[rm]);
   1359      1.1  christos 	  break;
   1360      1.1  christos 	case sel_vect:
   1361      1.1  christos 	  op2 = ValueFPR(vt, fmt_mdmx);
   1362      1.1  christos 	  result = ob_vector_round(cpu, cia, op2, ob_round[rm]);
   1363      1.1  christos 	  break;
   1364      1.1  christos 	case sel_imm:
   1365      1.1  christos 	  result = ob_map_round(cpu, cia, vt, ob_round[rm]);
   1366      1.1  christos 	  break;
   1367      1.1  christos 	}
   1368      1.1  christos       break;
   1369      1.1  christos     default:
   1370      1.1  christos       Unpredictable ();
   1371      1.1  christos     }
   1372      1.1  christos 
   1373      1.1  christos   return result;
   1374      1.1  christos }
   1375      1.1  christos 
   1376      1.1  christos 
   1377      1.1  christos /* Shuffle operation.  */
   1378      1.1  christos 
   1379      1.1  christos typedef struct {
   1380      1.1  christos   enum {vs, ss, vt} source;
   1381      1.1  christos   unsigned int      index;
   1382      1.1  christos } sh_map;
   1383      1.1  christos 
   1384      1.1  christos static const sh_map ob_shuffle[][8] = {
   1385      1.1  christos   /* MDMX 2.0 encodings (3-4, 6-7).  */
   1386      1.1  christos   /* vr5400   encoding  (5), otherwise.  */
   1387      1.1  christos   {                                                              }, /* RSVD */
   1388      1.1  christos   {{vt,4}, {vs,4}, {vt,5}, {vs,5}, {vt,6}, {vs,6}, {vt,7}, {vs,7}}, /* RSVD */
   1389      1.1  christos   {{vt,0}, {vs,0}, {vt,1}, {vs,1}, {vt,2}, {vs,2}, {vt,3}, {vs,3}}, /* RSVD */
   1390      1.1  christos   {{vs,0}, {ss,0}, {vs,1}, {ss,1}, {vs,2}, {ss,2}, {vs,3}, {ss,3}}, /* upsl */
   1391      1.1  christos   {{vt,1}, {vt,3}, {vt,5}, {vt,7}, {vs,1}, {vs,3}, {vs,5}, {vs,7}}, /* pach */
   1392      1.1  christos   {{vt,0}, {vt,2}, {vt,4}, {vt,6}, {vs,0}, {vs,2}, {vs,4}, {vs,6}}, /* pacl */
   1393      1.1  christos   {{vt,4}, {vs,4}, {vt,5}, {vs,5}, {vt,6}, {vs,6}, {vt,7}, {vs,7}}, /* mixh */
   1394      1.1  christos   {{vt,0}, {vs,0}, {vt,1}, {vs,1}, {vt,2}, {vs,2}, {vt,3}, {vs,3}}  /* mixl */
   1395      1.1  christos };
   1396      1.1  christos 
   1397      1.1  christos static const sh_map qh_shuffle[][4] = {
   1398      1.1  christos   {{vt,2}, {vs,2}, {vt,3}, {vs,3}},  /* mixh */
   1399      1.1  christos   {{vt,0}, {vs,0}, {vt,1}, {vs,1}},  /* mixl */
   1400      1.1  christos   {{vt,1}, {vt,3}, {vs,1}, {vs,3}},  /* pach */
   1401      1.1  christos   {                              },  /* RSVD */
   1402      1.1  christos   {{vt,1}, {vs,0}, {vt,3}, {vs,2}},  /* bfla */
   1403      1.1  christos   {                              },  /* RSVD */
   1404      1.1  christos   {{vt,2}, {vt,3}, {vs,2}, {vs,3}},  /* repa */
   1405      1.1  christos   {{vt,0}, {vt,1}, {vs,0}, {vs,1}}   /* repb */
   1406      1.1  christos };
   1407      1.1  christos 
   1408      1.1  christos 
   1409      1.1  christos unsigned64
   1410      1.1  christos mdmx_shuffle(sim_cpu *cpu,
   1411      1.1  christos 	     address_word cia,
   1412      1.1  christos 	     int shop,
   1413      1.1  christos 	     unsigned64 op1,
   1414      1.1  christos 	     unsigned64 op2)
   1415      1.1  christos {
   1416      1.1  christos   unsigned64 result = 0;
   1417      1.1  christos   int  i, s;
   1418      1.1  christos   int  op;
   1419      1.1  christos 
   1420      1.1  christos   if ((shop & 0x3) == 0x1)       /* QH format.  */
   1421      1.1  christos     {
   1422      1.1  christos       op = shop >> 2;
   1423      1.1  christos       s = 0;
   1424      1.1  christos       for (i = 0; i < 4; i++)
   1425      1.1  christos 	{
   1426      1.1  christos 	  unsigned64 v;
   1427      1.1  christos 
   1428      1.1  christos 	  switch (qh_shuffle[op][i].source)
   1429      1.1  christos 	    {
   1430      1.1  christos 	    case vs:
   1431      1.1  christos 	      v = op1;
   1432      1.1  christos 	      break;
   1433      1.1  christos 	    case vt:
   1434      1.1  christos 	      v = op2;
   1435      1.1  christos 	      break;
   1436      1.1  christos 	    default:
   1437      1.1  christos 	      Unpredictable ();
   1438      1.1  christos 	      v = 0;
   1439      1.1  christos 	    }
   1440      1.1  christos 	  result |= (((v >> 16*qh_shuffle[op][i].index) & 0xFFFF) << s);
   1441      1.1  christos 	  s += 16;
   1442      1.1  christos 	}
   1443      1.1  christos     }
   1444      1.1  christos   else if ((shop & 0x1) == 0x0)  /* OB format.  */
   1445      1.1  christos     {
   1446      1.1  christos       op = shop >> 1;
   1447      1.1  christos       s = 0;
   1448      1.1  christos       for (i = 0; i < 8; i++)
   1449      1.1  christos 	{
   1450      1.1  christos 	  unsigned8 b;
   1451      1.1  christos 	  unsigned int ishift = 8*ob_shuffle[op][i].index;
   1452      1.1  christos 
   1453      1.1  christos 	  switch (ob_shuffle[op][i].source)
   1454      1.1  christos 	    {
   1455      1.1  christos 	    case vs:
   1456      1.1  christos 	      b = (op1 >> ishift) & 0xFF;
   1457      1.1  christos 	      break;
   1458      1.1  christos 	    case ss:
   1459      1.1  christos 	      b = ((op1 >> ishift) & 0x80) ? 0xFF : 0;
   1460      1.1  christos 	      break;
   1461      1.1  christos 	    case vt:
   1462      1.1  christos 	      b = (op2 >> ishift) & 0xFF;
   1463      1.1  christos 	      break;
   1464      1.1  christos 	    default:
   1465      1.1  christos 	      Unpredictable ();
   1466      1.1  christos 	      b = 0;
   1467      1.1  christos 	    }
   1468      1.1  christos 	  result |= ((unsigned64)b << s);
   1469      1.1  christos 	  s += 8;
   1470      1.1  christos 	}
   1471      1.1  christos     }
   1472      1.1  christos   else
   1473      1.1  christos     Unpredictable ();
   1474      1.1  christos 
   1475      1.1  christos   return result;
   1476      1.1  christos }
   1477