Home | History | Annotate | Line # | Download | only in ppc
      1      1.1  christos #
      2      1.1  christos #   This file is part of the program psim.
      3      1.1  christos #
      4      1.1  christos #   Copyright 1994, 1995, 1996, 1997, 2003, 2004 Andrew Cagney
      5      1.1  christos #
      6      1.1  christos #   --
      7      1.1  christos #
      8      1.1  christos #   The pseudo-code that appears below, translated into C, was copied
      9      1.1  christos #   by Andrew Cagney of Moss Vale, Australia.
     10      1.1  christos #
     11      1.1  christos #   This pseudo-code is copied by permission from the publication
     12      1.1  christos #   "The PowerPC Architecture: A Specification for A New Family of
     13      1.1  christos #   RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by
     14      1.1  christos #   International Business Machines Corporation.
     15      1.1  christos #
     16      1.1  christos #   THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER
     17      1.1  christos #   EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES
     18      1.1  christos #   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     19      1.1  christos #
     20      1.1  christos #   --
     21      1.1  christos #
     22      1.1  christos #   This program is free software; you can redistribute it and/or modify
     23      1.1  christos #   it under the terms of the GNU General Public License as published by
     24      1.1  christos #   the Free Software Foundation; either version 3 of the License, or
     25      1.1  christos #   (at your option) any later version.
     26      1.1  christos #
     27      1.1  christos #   This program is distributed in the hope that it will be useful,
     28      1.1  christos #   but WITHOUT ANY WARRANTY; without even the implied warranty of
     29      1.1  christos #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     30      1.1  christos #   GNU General Public License for more details.
     31      1.1  christos #
     32      1.1  christos #   You should have received a copy of the GNU General Public License
     33      1.1  christos #   along with this program; if not, see <http://www.gnu.org/licenses/>.
     34      1.1  christos #
     35      1.1  christos 
     36      1.1  christos :cache::::RA:RA:
     37      1.1  christos :cache:::signed_word *:rA:RA:(cpu_registers(processor)->gpr + RA)
     38      1.1  christos :cache:::uint32_t:RA_BITMASK:RA:(1 << RA)
     39      1.1  christos :compute:::int:RA_is_0:RA:(RA == 0)
     40      1.1  christos :cache::::RT:RT:
     41      1.1  christos :cache:::signed_word *:rT:RT:(cpu_registers(processor)->gpr + RT)
     42      1.1  christos :cache:::uint32_t:RT_BITMASK:RT:(1 << RT)
     43      1.1  christos :cache::::RS:RS:
     44      1.1  christos :cache:::signed_word *:rS:RS:(cpu_registers(processor)->gpr + RS)
     45      1.1  christos :cache:::uint32_t:RS_BITMASK:RS:(1 << RS)
     46      1.1  christos :cache::::RB:RB:
     47      1.1  christos :cache:::signed_word *:rB:RB:(cpu_registers(processor)->gpr + RB)
     48      1.1  christos :cache:::uint32_t:RB_BITMASK:RB:(1 << RB)
     49      1.1  christos :scratch::::FRA:FRA:
     50      1.1  christos :cache:::uint64_t *:frA:FRA:(cpu_registers(processor)->fpr + FRA)
     51      1.1  christos :cache:::uint32_t:FRA_BITMASK:FRA:(1 << FRA)
     52      1.1  christos :scratch::::FRB:FRB:
     53      1.1  christos :cache:::uint64_t *:frB:FRB:(cpu_registers(processor)->fpr + FRB)
     54      1.1  christos :cache:::uint32_t:FRB_BITMASK:FRB:(1 << FRB)
     55      1.1  christos :scratch::::FRC:FRC:
     56      1.1  christos :cache:::uint64_t *:frC:FRC:(cpu_registers(processor)->fpr + FRC)
     57      1.1  christos :cache:::uint32_t:FRC_BITMASK:FRC:(1 << FRC)
     58      1.1  christos :scratch::::FRS:FRS:
     59      1.1  christos :cache:::uint64_t *:frS:FRS:(cpu_registers(processor)->fpr + FRS)
     60      1.1  christos :cache:::uint32_t:FRS_BITMASK:FRS:(1 << FRS)
     61      1.1  christos :scratch::::FRT:FRT:
     62      1.1  christos :cache:::uint64_t *:frT:FRT:(cpu_registers(processor)->fpr + FRT)
     63      1.1  christos :cache:::uint32_t:FRT_BITMASK:FRT:(1 << FRT)
     64      1.1  christos :cache:::unsigned_word:EXTS_SI:SI:((signed_word)(int16_t)instruction)
     65      1.1  christos :scratch::::BI:BI:
     66      1.1  christos :cache::::BIT32_BI:BI:BIT32(BI)
     67      1.1  christos :cache::::BF:BF:
     68      1.1  christos :cache:::uint32_t:BF_BITMASK:BF:(1 << BF)
     69      1.1  christos :scratch::::BA:BA:
     70      1.1  christos :cache::::BIT32_BA:BA:BIT32(BA)
     71      1.1  christos :cache:::uint32_t:BA_BITMASK:BA:(1 << BA)
     72      1.1  christos :scratch::::BB:BB:
     73      1.1  christos :cache::::BIT32_BB:BB:BIT32(BB)
     74      1.1  christos :cache:::uint32_t:BB_BITMASK:BB:(1 << BB)
     75      1.1  christos :cache::::BT:BT:
     76      1.1  christos :cache:::uint32_t:BT_BITMASK:BT:(1 << BT)
     77      1.1  christos :cache:::unsigned_word:EXTS_BD_0b00:BD:(((signed_word)(int16_t)instruction) & ~3)
     78      1.1  christos :cache:::unsigned_word:EXTS_LI_0b00:LI:((((signed_word)(int32_t)(instruction << 6)) >> 6) & ~0x3)
     79      1.1  christos :cache:::unsigned_word:EXTS_D:D:((signed_word)(int16_t)(instruction))
     80      1.1  christos :cache:::unsigned_word:EXTS_DS_0b00:DS:(((signed_word)(int16_t)instruction) & ~0x3)
     81      1.1  christos #:compute:::int:SPR_is_256:SPR:(SPR == 256)
     82      1.1  christos 
     84      1.1  christos # PowerPC models
     85      1.1  christos ::model:604:ppc604:  PPC_UNIT_BAD,   PPC_UNIT_BAD,   1,  1,  0
     86      1.1  christos ::model:603e:ppc603e:PPC_UNIT_BAD,   PPC_UNIT_BAD,   1,  1,  0
     87      1.1  christos ::model:603:ppc603:  PPC_UNIT_BAD,   PPC_UNIT_BAD,   1,  1,  0
     88      1.1  christos ::model:601:ppc601:  PPC_UNIT_BAD,   PPC_UNIT_BAD,   1,  1,  0
     89      1.1  christos 
     90      1.1  christos # Flags for model.h
     91      1.1  christos ::model-macro:::
     92      1.1  christos 	#define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \
     93      1.1  christos 		do { \
     94      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) { \
     95      1.1  christos 		    if (RC) \
     96      1.1  christos 		      ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
     97      1.1  christos 		    else \
     98      1.1  christos 		      ppc_insn_int(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
     99      1.1  christos 		  } \
    100      1.1  christos 		} while (0)
    101      1.1  christos 
    102      1.1  christos 	#define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \
    103      1.1  christos 		do { \
    104      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) \
    105      1.1  christos 		    ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
    106      1.1  christos 		} while (0)
    107      1.1  christos 
    108      1.1  christos 	#define PPC_INSN_CR(OUT_MASK, IN_MASK) \
    109      1.1  christos 		do { \
    110      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) \
    111      1.1  christos 		    ppc_insn_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
    112      1.1  christos 		} while (0)
    113      1.1  christos 
    114      1.1  christos 	#define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \
    115      1.1  christos 		do { \
    116      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) { \
    117      1.1  christos 		    if (RC) \
    118      1.1  christos 		      ppc_insn_float(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
    119      1.1  christos 		    else \
    120      1.1  christos 		      ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
    121      1.1  christos 		  } \
    122      1.1  christos 		} while (0)
    123      1.1  christos 
    124      1.1  christos 	#define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \
    125      1.1  christos 		do { \
    126      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) \
    127      1.1  christos 		    ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
    128      1.1  christos 		} while (0)
    129      1.1  christos 
    130      1.1  christos 	#define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \
    131      1.1  christos 		do { \
    132      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) \
    133      1.1  christos 		    ppc_insn_int_float(MY_INDEX, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \
    134      1.1  christos 		} while (0)
    135      1.1  christos 
    136      1.1  christos 	#define PPC_INSN_FROM_SPR(INT_MASK, SPR) \
    137      1.1  christos 		do { \
    138      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) \
    139      1.1  christos 		    ppc_insn_from_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
    140      1.1  christos 		} while (0)
    141      1.1  christos 
    142      1.1  christos 	#define PPC_INSN_TO_SPR(INT_MASK, SPR) \
    143      1.1  christos 		do { \
    144      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) \
    145      1.1  christos 		    ppc_insn_to_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
    146      1.1  christos 		} while (0)
    147      1.1  christos 
    148      1.1  christos 	#define PPC_INSN_MFCR(INT_MASK) \
    149      1.1  christos 		do { \
    150      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) \
    151      1.1  christos 		    ppc_insn_mfcr(MY_INDEX, cpu_model(processor), INT_MASK); \
    152      1.1  christos 		} while (0)
    153      1.1  christos 
    154      1.1  christos 	#define PPC_INSN_MTCR(INT_MASK, FXM) \
    155      1.1  christos 		do { \
    156      1.1  christos 		  if (CURRENT_MODEL_ISSUE > 0) \
    157      1.1  christos 		    ppc_insn_mtcr(MY_INDEX, cpu_model(processor), INT_MASK, FXM); \
    158      1.1  christos 		} while (0)
    159      1.1  christos 
    160      1.1  christos ::model-data:::
    161      1.1  christos 	typedef enum _ppc_function_unit {
    162      1.1  christos 	  PPC_UNIT_BAD,				/* unknown function unit */
    163      1.1  christos 	  PPC_UNIT_IU,				/* integer unit (601/603 style) */
    164      1.1  christos 	  PPC_UNIT_SRU,				/* system register unit (601/603 style) */
    165      1.1  christos 	  PPC_UNIT_SCIU1,			/* 1st single cycle integer unit (604 style) */
    166      1.1  christos 	  PPC_UNIT_SCIU2,			/* 2nd single cycle integer unit (604 style) */
    167      1.1  christos 	  PPC_UNIT_MCIU,			/* multiple cycle integer unit (604 style) */
    168      1.1  christos 	  PPC_UNIT_FPU,				/* floating point unit */
    169      1.1  christos 	  PPC_UNIT_LSU,				/* load/store unit */
    170      1.1  christos 	  PPC_UNIT_BPU,				/* branch unit */
    171      1.1  christos 	  nr_ppc_function_units
    172      1.1  christos 	} ppc_function_unit;
    173      1.1  christos 
    174      1.1  christos 	/* Structure to hold timing information on a per instruction basis */
    175      1.1  christos 	struct _model_time {
    176      1.1  christos 	  ppc_function_unit first_unit;			/* first functional unit this insn could use */
    177      1.1  christos 	  ppc_function_unit second_unit;		/* second functional unit this insn could use */
    178      1.1  christos 	  int16_t	    issue;			/* # cycles before function unit can process other insns */
    179      1.1  christos 	  int16_t	    done;			/* # cycles before insn is done */
    180      1.1  christos 	  uint32_t	    flags;			/* any flags that are needed */
    181      1.1  christos 	};
    182      1.1  christos 
    183      1.1  christos 	/* Register mappings in status masks */
    184      1.1  christos 	#define PPC_CR_REG	0			/* start of CR0 .. CR7 */
    185      1.1  christos 	#define PPC_FPSCR_REG	(PPC_CR_REG + 8)	/* start of fpscr register */
    186      1.1  christos 
    187      1.1  christos 	#define PPC_NO_SPR	(-1)			/* flag for no SPR register */
    188      1.1  christos 
    189      1.1  christos 	/* Return if 1 bit set */
    190      1.1  christos 	#define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0)
    191      1.1  christos 
    192      1.1  christos 	/* Structure for each functional unit that is busy */
    193      1.1  christos 	typedef struct _model_busy model_busy;
    194      1.1  christos 	struct _model_busy {
    195      1.1  christos 	  model_busy *next;				/* next function unit */
    196      1.1  christos 	  ppc_function_unit unit;			/* function unit name */
    197      1.1  christos 	  uint32_t int_busy;				/* int registers that are busy */
    198      1.1  christos 	  uint32_t fp_busy;				/* floating point registers that are busy */
    199      1.1  christos 	  uint32_t cr_fpscr_busy;			/* CR/FPSCR registers that are busy */
    200      1.1  christos 	  int16_t spr_busy;				/* SPR register that is busy or PPC_NO_SPR */
    201      1.1  christos 	  uint32_t vr_busy;				/* AltiVec registers that are busy */
    202      1.1  christos 	  int16_t vscr_busy;				/* AltiVec status register busy */
    203      1.1  christos 	  int16_t issue;				/* # of cycles until unit can accept another insn */
    204      1.1  christos 	  int16_t done;				/* # of cycles until insn is done */
    205      1.1  christos 	  int16_t nr_writebacks;			/* # of registers this unit writes back */
    206      1.1  christos 	};
    207      1.1  christos 	
    208      1.1  christos 	/* Structure to hold the current state information for the simulated CPU model */
    209      1.1  christos 	struct _model_data {
    210      1.1  christos 	  cpu *processor;				/* point back to processor */
    211      1.1  christos 	  const char *name;				/* model name */
    212      1.1  christos 	  const model_time *timing;			/* timing information */
    213      1.1  christos 	  model_busy busy_head;				/* dummy entry to head list of busy function units */
    214      1.1  christos 	  model_busy *busy_tail;			/* tail of list of busy function units */
    215      1.1  christos 	  model_busy *free_list;			/* list of model_busy structs not in use */
    216      1.1  christos 	  count_type nr_cycles;				/* # cycles */
    217      1.1  christos 	  count_type nr_branches;			/* # branches */
    218      1.1  christos 	  count_type nr_branches_fallthrough;		/* # conditional branches that fell through */
    219      1.1  christos 	  count_type nr_branch_predict_trues;		/* # branches predicted correctly */
    220      1.1  christos 	  count_type nr_branch_predict_falses;		/* # branches predicted incorrectly */
    221      1.1  christos 	  count_type nr_branch_conditional[32];		/* # of each type of bc */
    222      1.1  christos 	  count_type nr_mtcrf_crs[9];			/* # of CR's moved in a mtcrf instruction */
    223      1.1  christos 	  count_type nr_stalls_data;			/* # of stalls for data */
    224      1.1  christos 	  count_type nr_stalls_unit;			/* # of stalls waiting for a function unit */
    225      1.1  christos 	  count_type nr_stalls_serialize;		/* # of stalls waiting for things to quiet down */
    226      1.1  christos 	  count_type nr_stalls_writeback;		/* # of stalls waiting for a writeback slot */
    227      1.1  christos 	  count_type nr_units[nr_ppc_function_units];	/* function unit counts */
    228      1.1  christos 	  int max_nr_writebacks;			/* max # of writeback slots available */
    229      1.1  christos 	  uint32_t int_busy;				/* int registers that are busy */
    230      1.1  christos 	  uint32_t fp_busy;				/* floating point registers that are busy */
    231      1.1  christos 	  uint32_t cr_fpscr_busy;			/* CR/FPSCR registers that are busy */
    232      1.1  christos 	  uint8_t spr_busy[nr_of_sprs];		/* SPR registers that are busy */
    233      1.1  christos 	  uint32_t vr_busy;				/* AltiVec registers that are busy */
    234      1.1  christos 	  uint8_t vscr_busy;				/* AltiVec SC register busy */
    235      1.1  christos 	  uint8_t busy[nr_ppc_function_units];	/* whether a function is busy or not */
    236      1.1  christos 	};
    237      1.1  christos 
    238      1.1  christos 	static const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
    239      1.1  christos 	  "unknown functional unit instruction",
    240      1.1  christos 	  "integer functional unit instruction",
    241      1.1  christos 	  "system register functional unit instruction",
    242      1.1  christos 	  "1st single cycle integer functional unit instruction",
    243      1.1  christos 	  "2nd single cycle integer functional unit instruction",
    244      1.1  christos 	  "multiple cycle integer functional unit instruction",
    245      1.1  christos 	  "floating point functional unit instruction",
    246      1.1  christos 	  "load/store functional unit instruction",
    247      1.1  christos 	  "branch functional unit instruction",
    248      1.1  christos 	};
    249      1.1  christos 
    250      1.1  christos 	static const char *const ppc_branch_conditional_name[32] = {
    251      1.1  christos 	  "branch if --CTR != 0 and condition is FALSE",				/* 0000y */
    252      1.1  christos 	  "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
    253      1.1  christos 	  "branch if --CTR == 0 and condition is FALSE",				/* 0001y */
    254      1.1  christos 	  "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
    255      1.1  christos 	  "branch if the condition is FALSE",						/* 001zy */
    256      1.1  christos 	  "branch if the condition is FALSE, reverse branch likely",
    257      1.1  christos 	  "branch if the condition is FALSE (ignored bit 1 set to 1)",			/* 001zy */
    258      1.1  christos 	  "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
    259      1.1  christos 	  "branch if --CTR != 0 and condition is TRUE",					/* 0100y */
    260      1.1  christos 	  "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
    261      1.1  christos 	  "branch if --CTR == 0 and condition is TRUE",					/* 0101y */
    262      1.1  christos 	  "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
    263      1.1  christos 	  "branch if the condition is TRUE",						/* 011zy */
    264      1.1  christos 	  "branch if the condition is TRUE, reverse branch likely",
    265      1.1  christos 	  "branch if the condition is TRUE (ignored bit 1 set to 1)",			/* 011zy */
    266      1.1  christos 	  "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
    267      1.1  christos 	  "branch if --CTR != 0",							/* 1z00y */
    268      1.1  christos 	  "branch if --CTR != 0, reverse branch likely",
    269      1.1  christos 	  "branch if --CTR == 0",							/* 1z01y */
    270      1.1  christos 	  "branch if --CTR == 0, reverse branch likely",
    271      1.1  christos 	  "branch always",								/* 1z1zz */
    272      1.1  christos 	  "branch always (ignored bit 5 set to 1)",
    273      1.1  christos 	  "branch always (ignored bit 4 set to 1)",					/* 1z1zz */
    274      1.1  christos 	  "branch always (ignored bits 4,5 set to 1)",
    275      1.1  christos 	  "branch if --CTR != 0 (ignored bit 1 set to 1)",				/* 1z00y */
    276      1.1  christos 	  "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
    277      1.1  christos 	  "branch if --CTR == 0 (ignored bit 1 set to 1)",				/* 1z01y */
    278      1.1  christos 	  "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
    279      1.1  christos 	  "branch always (ignored bit 1 set to 1)",					/* 1z1zz */
    280      1.1  christos 	  "branch always (ignored bits 1,5 set to 1)",
    281      1.1  christos 	  "branch always (ignored bits 1,4 set to 1)",					/* 1z1zz */
    282      1.1  christos 	  "branch always (ignored bits 1,4,5 set to 1)",
    283      1.1  christos 	};
    284      1.1  christos 
    285      1.1  christos 	static const char *const ppc_nr_mtcrf_crs[9] = {
    286      1.1  christos 	  "mtcrf moving 0 CRs",
    287      1.1  christos 	  "mtcrf moving 1 CR",
    288      1.1  christos 	  "mtcrf moving 2 CRs",
    289      1.1  christos 	  "mtcrf moving 3 CRs",
    290      1.1  christos 	  "mtcrf moving 4 CRs",
    291      1.1  christos 	  "mtcrf moving 5 CRs",
    292      1.1  christos 	  "mtcrf moving 6 CRs",
    293      1.1  christos 	  "mtcrf moving 7 CRs",
    294      1.1  christos 	  "mtcrf moving all CRs",
    295      1.1  christos 	};
    296      1.1  christos 
    298      1.1  christos # Trace releasing resources
    299      1.1  christos void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
    300      1.1  christos 	int i;
    301      1.1  christos 	TRACE(trace_model,("done, %s, %d writeback%s\n", ppc_function_unit_name[busy->unit],
    302      1.1  christos 			   busy->nr_writebacks, busy->nr_writebacks == 1 ? "" : "s"));
    303      1.1  christos 	if (busy->int_busy) {
    304      1.1  christos 	  for(i = 0; i < 32; i++) {
    305      1.1  christos 	    if (((1 << i) & busy->int_busy) != 0) {
    306      1.1  christos 	      TRACE(trace_model, ("Register r%d is now available.\n", i));
    307      1.1  christos 	    }
    308      1.1  christos 	  }
    309      1.1  christos 	}
    310      1.1  christos 	if (busy->fp_busy) {
    311      1.1  christos 	  for(i = 0; i < 32; i++) {
    312      1.1  christos 	    if (((1 << i) & busy->fp_busy) != 0) {
    313      1.1  christos 	      TRACE(trace_model, ("Register f%d is now available.\n", i));
    314      1.1  christos 	    }
    315      1.1  christos 	  }
    316      1.1  christos 	}
    317      1.1  christos 	if (busy->cr_fpscr_busy) {
    318      1.1  christos 	  for(i = 0; i < 8; i++) {
    319      1.1  christos 	    if (((1 << i) & busy->cr_fpscr_busy) != 0) {
    320      1.1  christos 	      TRACE(trace_model, ("Register cr%d is now available.\n", i));
    321      1.1  christos 	    }
    322      1.1  christos 	  }
    323      1.1  christos 	  if (busy->cr_fpscr_busy & 0x100)
    324      1.1  christos 	    TRACE(trace_model, ("Register fpscr is now available.\n"));
    325      1.1  christos 	}
    326      1.1  christos 	if (busy->spr_busy != PPC_NO_SPR)
    327      1.1  christos 	  TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
    328      1.1  christos 	if (busy->vr_busy) {
    329      1.1  christos 	  for(i = 0; i < 32; i++) {
    330      1.1  christos 	    if (((1 << i) & busy->vr_busy) != 0) {
    331      1.1  christos 	      TRACE(trace_model, ("Register v%d is now available.\n", i));
    332      1.1  christos 	    }
    333      1.1  christos 	  }
    334      1.1  christos 	}
    335      1.1  christos 	if (busy->vscr_busy)
    336      1.1  christos 	  TRACE(trace_model, ("VSCR Register %s is now available.\n", spr_name(busy->spr_busy)));
    337      1.1  christos 
    338      1.1  christos # Trace making registers busy
    339      1.1  christos void::model-static::model_trace_make_busy:model_data *model_ptr, uint32_t int_mask, uint32_t fp_mask, uint32_t cr_mask
    340      1.1  christos 	int i;
    341      1.1  christos 	if (int_mask) {
    342      1.1  christos 	  for(i = 0; i < 32; i++) {
    343      1.1  christos 	    if (((1 << i) & int_mask) != 0) {
    344      1.1  christos 	      TRACE(trace_model, ("Register r%d is now busy.\n", i));
    345      1.1  christos 	    }
    346      1.1  christos 	  }
    347      1.1  christos 	}
    348      1.1  christos 	if (fp_mask) {
    349      1.1  christos 	  for(i = 0; i < 32; i++) {
    350      1.1  christos 	    if (((1 << i) & fp_mask) != 0) {
    351      1.1  christos 	      TRACE(trace_model, ("Register f%d is now busy.\n", i));
    352      1.1  christos 	    }
    353      1.1  christos 	  }
    354      1.1  christos 	}
    355      1.1  christos 	if (cr_mask) {
    356      1.1  christos 	  for(i = 0; i < 8; i++) {
    357      1.1  christos 	    if (((1 << i) & cr_mask) != 0) {
    358      1.1  christos 	      TRACE(trace_model, ("Register cr%d is now busy.\n", i));
    359      1.1  christos 	    }
    360      1.1  christos 	  }
    361      1.1  christos 	}
    362      1.1  christos 
    363      1.1  christos # Trace waiting for registers to become available
    364      1.1  christos void::model-static::model_trace_busy_p:model_data *model_ptr, uint32_t int_busy, uint32_t fp_busy, uint32_t cr_or_fpscr_busy, int spr_busy
    365      1.1  christos 	int i;
    366      1.1  christos 	if (int_busy) {
    367      1.1  christos 	  int_busy &= model_ptr->int_busy;
    368      1.1  christos 	  for(i = 0; i < 32; i++) {
    369      1.1  christos 	    if (((1 << i) & int_busy) != 0) {
    370      1.1  christos 	      TRACE(trace_model, ("Waiting for register r%d.\n", i));
    371      1.1  christos 	    }
    372      1.1  christos 	  }
    373      1.1  christos 	}
    374      1.1  christos 	if (fp_busy) {
    375      1.1  christos 	  fp_busy &= model_ptr->fp_busy;
    376      1.1  christos 	  for(i = 0; i < 32; i++) {
    377      1.1  christos 	    if (((1 << i) & fp_busy) != 0) {
    378      1.1  christos 	      TRACE(trace_model, ("Waiting for register f%d.\n", i));
    379      1.1  christos 	    }
    380      1.1  christos 	  }
    381      1.1  christos 	}
    382      1.1  christos 	if (cr_or_fpscr_busy) {
    383      1.1  christos 	  cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
    384      1.1  christos 	  for(i = 0; i < 8; i++) {
    385      1.1  christos 	    if (((1 << i) & cr_or_fpscr_busy) != 0) {
    386      1.1  christos 	      TRACE(trace_model, ("Waiting for register cr%d.\n", i));
    387      1.1  christos 	    }
    388      1.1  christos 	  }
    389      1.1  christos 	  if (cr_or_fpscr_busy & 0x100)
    390      1.1  christos 	    TRACE(trace_model, ("Waiting for register fpscr.\n"));
    391      1.1  christos 	}
    392      1.1  christos 	if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
    393      1.1  christos 	  TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
    394      1.1  christos 
    396      1.1  christos # Advance state to next cycle, releasing any registers allocated
    397      1.1  christos void::model-internal::model_new_cycle:model_data *model_ptr
    398      1.1  christos 	model_busy *cur_busy  = model_ptr->busy_head.next;
    399      1.1  christos 	model_busy *free_list = model_ptr->free_list;
    400      1.1  christos 	model_busy *busy_tail = &model_ptr->busy_head;
    401      1.1  christos 	int nr_writebacks     = model_ptr->max_nr_writebacks;
    402      1.1  christos 	model_busy *next;
    403      1.1  christos 
    404      1.1  christos 	model_ptr->nr_cycles++;
    405      1.1  christos 	TRACE(trace_model,("New cycle %lu\n", (unsigned long)model_ptr->nr_cycles));
    406      1.1  christos 	for ( ; cur_busy; cur_busy = next) {
    407      1.1  christos 	  next = cur_busy->next;
    408      1.1  christos 	  if (--cur_busy->done <= 0) {		/* function unit done, release registers if we have writeback slots */
    409      1.1  christos 	    nr_writebacks -= cur_busy->nr_writebacks;
    410      1.1  christos 	    if (nr_writebacks >= 0) {
    411      1.1  christos 	      model_ptr->int_busy &= ~cur_busy->int_busy;
    412      1.1  christos 	      model_ptr->fp_busy &= ~cur_busy->fp_busy;
    413      1.1  christos 	      model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
    414      1.1  christos 	      if (cur_busy->spr_busy != PPC_NO_SPR)
    415      1.1  christos 		model_ptr->spr_busy[cur_busy->spr_busy] = 0;
    416      1.1  christos 	      model_ptr->vr_busy &= ~cur_busy->vr_busy;
    417      1.1  christos 	      model_ptr->vscr_busy = ~cur_busy->vscr_busy;
    418      1.1  christos 
    419      1.1  christos 	      if (WITH_TRACE && ppc_trace[trace_model])
    420      1.1  christos 		model_trace_release(model_ptr, cur_busy);
    421      1.1  christos 
    422      1.1  christos 	      model_ptr->busy[cur_busy->unit] = 0;
    423      1.1  christos 	      cur_busy->next = free_list;
    424      1.1  christos 	      free_list = cur_busy;
    425      1.1  christos 	    }
    426      1.1  christos 	    else {	/* writeback slots not available */
    427      1.1  christos 	      TRACE(trace_model,("%d writeback slot%s not available for %s\n",
    428      1.1  christos 				 cur_busy->nr_writebacks,
    429      1.1  christos 				 cur_busy->nr_writebacks == 1 ? " is" : "s are",
    430      1.1  christos 				 ppc_function_unit_name[cur_busy->unit]));
    431      1.1  christos 	      cur_busy->done++;			/* undo -- above */
    432      1.1  christos 	      model_ptr->nr_stalls_writeback++;
    433      1.1  christos 	      busy_tail->next = cur_busy;
    434      1.1  christos 	      busy_tail = cur_busy;
    435      1.1  christos 	    }
    436      1.1  christos 	  }
    437      1.1  christos 	  else if (--cur_busy->issue <= 0) {	/* function unit pipelined, allow new use */
    438      1.1  christos 	    TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
    439      1.1  christos 	    model_ptr->busy[cur_busy->unit] = 0;
    440      1.1  christos 	    busy_tail->next = cur_busy;
    441      1.1  christos 	    busy_tail = cur_busy;
    442      1.1  christos 	  }
    443      1.1  christos 	  else {
    444      1.1  christos 	    TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
    445      1.1  christos 			       ppc_function_unit_name[cur_busy->unit],
    446      1.1  christos 			       cur_busy->issue,
    447      1.1  christos 			       cur_busy->done));
    448      1.1  christos 	    busy_tail->next = cur_busy;
    449      1.1  christos 	    busy_tail = cur_busy;
    450      1.1  christos 	  }
    451      1.1  christos 	}
    452      1.1  christos 
    453      1.1  christos 	busy_tail->next = (model_busy *)0;
    454      1.1  christos 	model_ptr->busy_tail = busy_tail;
    455      1.1  christos 	model_ptr->free_list = free_list;
    456      1.1  christos 
    457      1.1  christos # Mark a function unit as busy, return the busy structure
    458      1.1  christos model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
    459      1.1  christos 	model_busy *busy;
    460      1.1  christos 
    461      1.1  christos 	TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
    462      1.1  christos 
    463      1.1  christos 	if (!model_ptr->free_list) {
    464      1.1  christos 	  busy = ZALLOC(model_busy);
    465      1.1  christos 	}
    466      1.1  christos 	else {
    467      1.1  christos 	  busy = model_ptr->free_list;
    468      1.1  christos 	  model_ptr->free_list = busy->next;
    469      1.1  christos 	  busy->next = (model_busy *)0;
    470      1.1  christos 	  busy->int_busy = 0;
    471      1.1  christos 	  busy->fp_busy = 0;
    472      1.1  christos 	  busy->cr_fpscr_busy = 0;
    473      1.1  christos 	  busy->nr_writebacks = 0;
    474      1.1  christos 	  busy->vr_busy = 0;
    475      1.1  christos 	  busy->vscr_busy = 0;
    476      1.1  christos 	}
    477      1.1  christos 
    478      1.1  christos 	busy->unit = unit;
    479      1.1  christos 	busy->issue = issue;
    480      1.1  christos 	busy->done = done;
    481      1.1  christos 	busy->spr_busy = PPC_NO_SPR;
    482      1.1  christos 	model_ptr->busy_tail->next = busy;
    483      1.1  christos 	model_ptr->busy_tail = busy;
    484      1.1  christos 	model_ptr->busy[unit] = 1;
    485      1.1  christos 	model_ptr->nr_units[unit]++;
    486      1.1  christos 	return busy;
    487      1.1  christos 
    489      1.1  christos # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
    490      1.1  christos model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
    491      1.1  christos 	ppc_function_unit first_unit = time_ptr->first_unit;
    492      1.1  christos 	ppc_function_unit second_unit = time_ptr->second_unit;
    493      1.1  christos 	int stall_increment = 0;
    494      1.1  christos 
    495      1.1  christos 	for (;;) {
    496      1.1  christos 	  if (!model_ptr->busy[first_unit])
    497      1.1  christos 	    return model_make_busy(model_ptr, first_unit,
    498      1.1  christos 				   model_ptr->timing[index].issue,
    499      1.1  christos 				   model_ptr->timing[index].done);
    500      1.1  christos 
    501      1.1  christos 	  if (!model_ptr->busy[second_unit])
    502      1.1  christos 	    return model_make_busy(model_ptr, second_unit,
    503      1.1  christos 				   model_ptr->timing[index].issue,
    504      1.1  christos 				   model_ptr->timing[index].done);
    505      1.1  christos 
    506      1.1  christos 	  TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
    507      1.1  christos 	  model_ptr->nr_stalls_unit += stall_increment;		/* don't count first stall */
    508      1.1  christos 	  stall_increment = 1;
    509      1.1  christos 	  model_new_cycle(model_ptr);
    510      1.1  christos 	}
    511      1.1  christos 
    512      1.1  christos # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
    513      1.1  christos void::model-function::model_serialize:itable_index index, model_data *model_ptr
    514      1.1  christos 	while (model_ptr->busy_head.next) {
    515      1.1  christos 	  TRACE(trace_model,("waiting for pipeline to empty\n"));
    516      1.1  christos 	  model_ptr->nr_stalls_serialize++;
    517      1.1  christos 	  model_new_cycle(model_ptr);
    518      1.1  christos 	}
    519      1.1  christos 	(void) model_make_busy(model_ptr,
    520      1.1  christos 			       model_ptr->timing[index].first_unit,
    521      1.1  christos 			       model_ptr->timing[index].issue,
    522      1.1  christos 			       model_ptr->timing[index].done);
    523      1.1  christos 
    524      1.1  christos # Wait for a CR to become unbusy
    525      1.1  christos void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
    526      1.1  christos 	unsigned u;
    527      1.1  christos 	uint32_t cr_mask;
    528      1.1  christos 	int cr_var = 0;
    529      1.1  christos 	for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
    530      1.1  christos 	  cr_var++;
    531      1.1  christos 
    532      1.1  christos 	cr_mask = (1 << cr_var);
    533      1.1  christos 	while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
    534      1.1  christos 	  TRACE(trace_model,("waiting for CR %d\n", cr_var));
    535      1.1  christos 	  model_ptr->nr_stalls_data++;
    536      1.1  christos 	  model_new_cycle(model_ptr);
    537      1.1  christos 	}
    538      1.1  christos 
    539      1.1  christos # Schedule an instruction that takes integer input registers and produces output registers
    540      1.1  christos void::model-function::ppc_insn_int:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask
    541      1.1  christos 	const uint32_t int_mask = out_mask | in_mask;
    542      1.1  christos 	model_busy *busy_ptr;
    543      1.1  christos 
    544      1.1  christos 	if ((model_ptr->int_busy & int_mask) != 0) {
    545      1.1  christos 	  model_new_cycle(model_ptr);			/* don't count first dependency as a stall */
    546      1.1  christos 
    547      1.1  christos 	  while ((model_ptr->int_busy & int_mask) != 0) {
    548      1.1  christos 	    if (WITH_TRACE && ppc_trace[trace_model])
    549      1.1  christos 	      model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
    550      1.1  christos 
    551      1.1  christos 	    model_ptr->nr_stalls_data++;
    552      1.1  christos 	    model_new_cycle(model_ptr);
    553      1.1  christos 	  }
    554      1.1  christos 	}
    555      1.1  christos 
    556      1.1  christos 	busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
    557      1.1  christos 	model_ptr->int_busy |= out_mask;
    558      1.1  christos 	busy_ptr->int_busy |= out_mask;
    559      1.1  christos 	if (out_mask)
    560      1.1  christos 	  busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
    561      1.1  christos 
    562      1.1  christos 	if (WITH_TRACE && ppc_trace[trace_model])
    563      1.1  christos 	  model_trace_make_busy(model_ptr, out_mask, 0, 0);
    564      1.1  christos 
    565      1.1  christos # Schedule an instruction that takes integer input registers and produces output registers & sets a CR register
    566      1.1  christos void::model-function::ppc_insn_int_cr:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask, const uint32_t cr_mask
    567      1.1  christos 	const uint32_t int_mask = out_mask | in_mask;
    568      1.1  christos 	model_busy *busy_ptr;
    569      1.1  christos 
    570      1.1  christos 	if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
    571      1.1  christos 	  model_new_cycle(model_ptr);			/* don't count first dependency as a stall */
    572      1.1  christos 
    573      1.1  christos 	  while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
    574      1.1  christos 	    if (WITH_TRACE && ppc_trace[trace_model])
    575      1.1  christos 	      model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
    576      1.1  christos 
    577      1.1  christos 	    model_ptr->nr_stalls_data++;
    578      1.1  christos 	    model_new_cycle(model_ptr);
    579      1.1  christos 	  }
    580      1.1  christos 	}
    581      1.1  christos 
    582      1.1  christos 	busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
    583      1.1  christos 	model_ptr->int_busy |= out_mask;
    584      1.1  christos 	busy_ptr->int_busy |= out_mask;
    585      1.1  christos 	model_ptr->cr_fpscr_busy |= cr_mask;
    586      1.1  christos 	busy_ptr->cr_fpscr_busy |= cr_mask;
    587      1.1  christos 	if (out_mask)
    588      1.1  christos 	  busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
    589      1.1  christos 
    590      1.1  christos 	if (cr_mask)
    591      1.1  christos 	  busy_ptr->nr_writebacks++;
    592      1.1  christos 
    593      1.1  christos 	if (WITH_TRACE && ppc_trace[trace_model])
    594      1.1  christos 	  model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
    595      1.1  christos 
    596      1.1  christos 
    597      1.1  christos # Schedule an instruction that takes CR input registers and produces output CR registers
    598      1.1  christos void::model-function::ppc_insn_cr:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask
    599      1.1  christos 	const uint32_t cr_mask = out_mask | in_mask;
    600      1.1  christos 	model_busy *busy_ptr;
    601      1.1  christos 
    602      1.1  christos 	if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
    603      1.1  christos 	  model_new_cycle(model_ptr);			/* don't count first dependency as a stall */
    604      1.1  christos 
    605      1.1  christos 	  while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
    606      1.1  christos 	    if (WITH_TRACE && ppc_trace[trace_model])
    607      1.1  christos 	      model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
    608      1.1  christos 
    609      1.1  christos 	    model_ptr->nr_stalls_data++;
    610      1.1  christos 	    model_new_cycle(model_ptr);
    611      1.1  christos 	  }
    612      1.1  christos 	}
    613      1.1  christos 
    614      1.1  christos 	busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
    615      1.1  christos 	model_ptr->cr_fpscr_busy |= out_mask;
    616      1.1  christos 	busy_ptr->cr_fpscr_busy |= out_mask;
    617      1.1  christos 	if (out_mask)
    618      1.1  christos 	  busy_ptr->nr_writebacks = 1;
    619      1.1  christos 
    620      1.1  christos 	if (WITH_TRACE && ppc_trace[trace_model])
    621      1.1  christos 	  model_trace_make_busy(model_ptr, 0, 0, out_mask);
    622      1.1  christos 
    623      1.1  christos 
    624      1.1  christos # Schedule an instruction that takes floating point input registers and produces an output fp register
    625      1.1  christos void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask
    626      1.1  christos 	const uint32_t fp_mask = out_mask | in_mask;
    627      1.1  christos 	model_busy *busy_ptr;
    628      1.1  christos 
    629      1.1  christos 	if ((model_ptr->fp_busy & fp_mask) != 0) {
    630      1.1  christos 	  model_new_cycle(model_ptr);			/* don't count first dependency as a stall */
    631      1.1  christos 
    632      1.1  christos 	  while ((model_ptr->fp_busy & fp_mask) != 0) {
    633      1.1  christos 	    if (WITH_TRACE && ppc_trace[trace_model])
    634      1.1  christos 	      model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
    635      1.1  christos 
    636      1.1  christos 	    model_ptr->nr_stalls_data++;
    637      1.1  christos 	    model_new_cycle(model_ptr);
    638      1.1  christos 	  }
    639      1.1  christos 	}
    640      1.1  christos 
    641      1.1  christos 	busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
    642      1.1  christos 	model_ptr->fp_busy |= out_mask;
    643      1.1  christos 	busy_ptr->fp_busy |= out_mask;
    644      1.1  christos 	busy_ptr->nr_writebacks = 1;
    645      1.1  christos 	if (WITH_TRACE && ppc_trace[trace_model])
    646      1.1  christos 	  model_trace_make_busy(model_ptr, 0, out_mask, 0);
    647      1.1  christos 
    648      1.1  christos 
    649      1.1  christos # Schedule an instruction that takes floating point input registers and produces an output fp register & sets a CR reg
    650      1.1  christos void::model-function::ppc_insn_float_cr:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask, const uint32_t cr_mask
    651      1.1  christos 	const uint32_t fp_mask = out_mask | in_mask;
    652      1.1  christos 	model_busy *busy_ptr;
    653      1.1  christos 
    654      1.1  christos 	if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
    655      1.1  christos 	  model_new_cycle(model_ptr);			/* don't count first dependency as a stall */
    656      1.1  christos 
    657      1.1  christos 	  while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
    658      1.1  christos 	    if (WITH_TRACE && ppc_trace[trace_model])
    659      1.1  christos 	      model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
    660      1.1  christos 
    661      1.1  christos 	    model_ptr->nr_stalls_data++;
    662      1.1  christos 	    model_new_cycle(model_ptr);
    663      1.1  christos 	  }
    664      1.1  christos 	}
    665      1.1  christos 
    666      1.1  christos 	busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
    667      1.1  christos 	model_ptr->fp_busy |= out_mask;
    668      1.1  christos 	busy_ptr->fp_busy |= out_mask;
    669      1.1  christos 	model_ptr->cr_fpscr_busy |= cr_mask;
    670      1.1  christos 	busy_ptr->cr_fpscr_busy |= cr_mask;
    671      1.1  christos 	busy_ptr->nr_writebacks = (cr_mask) ? 2 : 1;
    672      1.1  christos 	if (WITH_TRACE && ppc_trace[trace_model])
    673      1.1  christos 	  model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
    674      1.1  christos 
    675      1.1  christos 
    676      1.1  christos # Schedule an instruction that takes both int/float input registers and produces output int/float registers
    677      1.1  christos void::model-function::ppc_insn_int_float:itable_index index, model_data *model_ptr, const uint32_t out_int_mask, const uint32_t out_fp_mask, const uint32_t in_int_mask, const uint32_t in_fp_mask
    678      1.1  christos 	const uint32_t int_mask = out_int_mask | in_int_mask;
    679      1.1  christos 	const uint32_t fp_mask = out_fp_mask | in_fp_mask;
    680      1.1  christos 	model_busy *busy_ptr;
    681      1.1  christos 
    682      1.1  christos 	if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
    683      1.1  christos 	  model_new_cycle(model_ptr);			/* don't count first dependency as a stall */
    684      1.1  christos 
    685      1.1  christos 	  while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
    686      1.1  christos 	    if (WITH_TRACE && ppc_trace[trace_model])
    687      1.1  christos 	      model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
    688      1.1  christos 
    689      1.1  christos 	    model_ptr->nr_stalls_data++;
    690      1.1  christos 	    model_new_cycle(model_ptr);
    691      1.1  christos 	  }
    692      1.1  christos 
    693      1.1  christos 	  busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
    694      1.1  christos 	  model_ptr->int_busy |= out_int_mask;
    695      1.1  christos 	  busy_ptr->int_busy |= out_int_mask;
    696      1.1  christos 	  model_ptr->fp_busy |= out_fp_mask;
    697      1.1  christos 	  busy_ptr->fp_busy |= out_fp_mask;
    698      1.1  christos 	  busy_ptr->nr_writebacks = ((out_int_mask) ? 1 : 0) + ((out_fp_mask) ? 1 : 0);
    699      1.1  christos 	  if (WITH_TRACE && ppc_trace[trace_model])
    700      1.1  christos 	    model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0);
    701      1.1  christos 	  return;
    702      1.1  christos 	}
    703      1.1  christos 
    704      1.1  christos # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
    705      1.1  christos void::model-function::ppc_insn_from_spr:itable_index index, model_data *model_ptr, const uint32_t int_mask, const unsigned nSPR
    706      1.1  christos 	model_busy *busy_ptr;
    707      1.1  christos 
    708      1.1  christos 	while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
    709      1.1  christos 	  if (WITH_TRACE && ppc_trace[trace_model])
    710      1.1  christos 	    model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
    711      1.1  christos 
    712      1.1  christos 	  model_ptr->nr_stalls_data++;
    713      1.1  christos 	  model_new_cycle(model_ptr);
    714      1.1  christos 	}
    715      1.1  christos 
    716      1.1  christos 	busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
    717      1.1  christos 	model_ptr->int_busy |= int_mask;
    718      1.1  christos 	busy_ptr->int_busy |= int_mask;
    719      1.1  christos 	busy_ptr->nr_writebacks = 1;
    720      1.1  christos 	if (WITH_TRACE && ppc_trace[trace_model])
    721      1.1  christos 	  model_trace_make_busy(model_ptr, int_mask, 0, 0);
    722      1.1  christos 
    723      1.1  christos # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
    724      1.1  christos void::model-function::ppc_insn_to_spr:itable_index index, model_data *model_ptr, const uint32_t int_mask, const unsigned nSPR
    725      1.1  christos 	model_busy *busy_ptr;
    726      1.1  christos 
    727      1.1  christos 	while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
    728      1.1  christos 	  if (WITH_TRACE && ppc_trace[trace_model])
    729      1.1  christos 	    model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
    730      1.1  christos 
    731      1.1  christos 	  model_ptr->nr_stalls_data++;
    732      1.1  christos 	  model_new_cycle(model_ptr);
    733      1.1  christos 	}
    734      1.1  christos 
    735      1.1  christos 	busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
    736      1.1  christos 	busy_ptr->spr_busy = nSPR;
    737      1.1  christos 	model_ptr->spr_busy[nSPR] = 1;
    738      1.1  christos 	busy_ptr->nr_writebacks = 1;
    739      1.1  christos 	TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));
    740      1.1  christos 
    741      1.1  christos # Schedule a MFCR instruction that moves the CR into an integer register
    742      1.1  christos void::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, uint32_t int_mask
    743      1.1  christos 	const uint32_t cr_mask = 0xff;
    744      1.1  christos 	model_busy *busy_ptr;
    745      1.1  christos 
    746      1.1  christos 	while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
    747      1.1  christos 	  if (WITH_TRACE && ppc_trace[trace_model])
    748      1.1  christos 	    model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
    749      1.1  christos 
    750      1.1  christos 	  model_ptr->nr_stalls_data++;
    751      1.1  christos 	  model_new_cycle(model_ptr);
    752      1.1  christos 	}
    753      1.1  christos 
    754      1.1  christos 	busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
    755      1.1  christos 	model_ptr->int_busy |= int_mask;
    756      1.1  christos 	busy_ptr->int_busy |= int_mask;
    757      1.1  christos 	busy_ptr->nr_writebacks = 1;
    758      1.1  christos 	if (WITH_TRACE && ppc_trace[trace_model])
    759      1.1  christos 	  model_trace_make_busy(model_ptr, int_mask, 0, 0);
    760      1.1  christos 
    761      1.1  christos # Schedule a MTCR instruction that moves an integer register into the CR
    762      1.1  christos void::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, uint32_t int_mask, unsigned FXM
    763      1.1  christos 	int f;
    764      1.1  christos 	int nr_crs = 0;
    765      1.1  christos 	uint32_t cr_mask = 0;
    766      1.1  christos 	const model_time *normal_time = &model_ptr->timing[index];
    767      1.1  christos 	static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0 };
    768      1.1  christos 	model_busy *busy_ptr;
    769      1.1  christos 
    770      1.1  christos 	for (f = 0; f < 8; f++) {
    771      1.1  christos 	  if (FXM & (0x80 >> f)) {
    772      1.1  christos 	    cr_mask |= (1 << f);
    773      1.1  christos 	    nr_crs++;
    774      1.1  christos 	  }
    775      1.1  christos 	}
    776      1.1  christos 
    777      1.1  christos 	while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
    778      1.1  christos 	  if (WITH_TRACE && ppc_trace[trace_model])
    779      1.1  christos 	    model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
    780      1.1  christos 
    781      1.1  christos 	  model_ptr->nr_stalls_data++;
    782      1.1  christos 	  model_new_cycle(model_ptr);
    783      1.1  christos 	}
    784      1.1  christos 
    785      1.1  christos 	/* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */
    786      1.1  christos 	if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) {
    787      1.1  christos 	  normal_time = &ppc604_1bit_time;
    788      1.1  christos 	}
    789      1.1  christos 
    790      1.1  christos 	busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
    791      1.1  christos 	busy_ptr->cr_fpscr_busy |= cr_mask;
    792      1.1  christos 	model_ptr->cr_fpscr_busy |= cr_mask;
    793      1.1  christos 	model_ptr->nr_mtcrf_crs[nr_crs]++;
    794      1.1  christos 	busy_ptr->nr_writebacks = 1;
    795      1.1  christos 	if (WITH_TRACE && ppc_trace[trace_model])
    796      1.1  christos 	  model_trace_make_busy(model_ptr, 0, 0, cr_mask);
    797      1.1  christos 
    799      1.1  christos model_data *::model-function::model_create:cpu *processor
    800      1.1  christos 	model_data *model_ptr = ZALLOC(model_data);
    801      1.1  christos 	model_ptr->name = model_name[CURRENT_MODEL];
    802      1.1  christos 	model_ptr->timing = model_time_mapping[CURRENT_MODEL];
    803      1.1  christos 	model_ptr->processor = processor;
    804      1.1  christos 	model_ptr->nr_cycles = 1;
    805      1.1  christos 	model_ptr->busy_tail = &model_ptr->busy_head;
    806      1.1  christos 	switch (CURRENT_MODEL) {
    807      1.1  christos 	case MODEL_ppc601:  model_ptr->max_nr_writebacks = 1; break;	/* ??? */
    808      1.1  christos 	case MODEL_ppc603:  model_ptr->max_nr_writebacks = 2; break;
    809      1.1  christos 	case MODEL_ppc603e: model_ptr->max_nr_writebacks = 2; break;
    810      1.1  christos 	case MODEL_ppc604:  model_ptr->max_nr_writebacks = 2; break;
    811      1.1  christos 	default: error ("Unknown model %d\n", CURRENT_MODEL);
    812      1.1  christos 	}
    813      1.1  christos 	return model_ptr;
    814      1.1  christos 
    815      1.1  christos void::model-function::model_init:model_data *model_ptr
    816      1.1  christos 
    817      1.1  christos void::model-function::model_halt:model_data *model_ptr
    818      1.1  christos 	/* Let pipeline drain */
    819      1.1  christos 	while (model_ptr->busy_head.next)
    820      1.1  christos 	  model_new_cycle(model_ptr);
    821      1.1  christos 
    822      1.1  christos unsigned_word::model-function::model_get_number_of_stalls:model_data *model_ptr
    823      1.1  christos 	return (model_ptr->nr_stalls_data
    824      1.1  christos 	        + model_ptr->nr_stalls_unit
    825      1.1  christos 	        + model_ptr->nr_stalls_serialize
    826      1.1  christos 	        + model_ptr->nr_stalls_writeback);
    827      1.1  christos 
    828      1.1  christos unsigned_word::model-function::model_get_number_of_cycles:model_data *model_ptr
    829      1.1  christos 	return (model_ptr->nr_cycles);
    830      1.1  christos 
    831      1.1  christos model_print *::model-function::model_mon_info:model_data *model_ptr
    832      1.1  christos 	model_print *head;
    833      1.1  christos 	model_print *tail;
    834      1.1  christos 	ppc_function_unit i;
    835      1.1  christos 	count_type nr_insns;
    836      1.1  christos 	int j;
    837      1.1  christos 
    838      1.1  christos 	head = tail = ZALLOC(model_print);
    839      1.1  christos 	tail->count = model_ptr->nr_cycles;
    840      1.1  christos 	tail->name = "cycle";
    841      1.1  christos 	tail->suffix_plural = "s";
    842      1.1  christos 	tail->suffix_singular = "";
    843      1.1  christos 
    844      1.1  christos 	if (model_ptr->nr_stalls_data) {
    845      1.1  christos 	  tail->next = ZALLOC(model_print);
    846      1.1  christos 	  tail = tail->next;
    847      1.1  christos 	  tail->count = model_ptr->nr_stalls_data;
    848      1.1  christos 	  tail->name = "stall";
    849      1.1  christos 	  tail->suffix_plural = "s waiting for data";
    850      1.1  christos 	  tail->suffix_singular = " waiting for data";
    851      1.1  christos 	}
    852      1.1  christos 
    853      1.1  christos 	if (model_ptr->nr_stalls_unit) {
    854      1.1  christos 	  tail->next = ZALLOC(model_print);
    855      1.1  christos 	  tail = tail->next;
    856      1.1  christos 	  tail->count = model_ptr->nr_stalls_unit;
    857      1.1  christos 	  tail->name = "stall";
    858      1.1  christos 	  tail->suffix_plural = "s waiting for a function unit";
    859      1.1  christos 	  tail->suffix_singular = " waiting for a function unit";
    860      1.1  christos 	}
    861      1.1  christos 
    862      1.1  christos 	if (model_ptr->nr_stalls_serialize) {
    863      1.1  christos 	  tail->next = ZALLOC(model_print);
    864      1.1  christos 	  tail = tail->next;
    865      1.1  christos 	  tail->count = model_ptr->nr_stalls_serialize;
    866      1.1  christos 	  tail->name = "stall";
    867      1.1  christos 	  tail->suffix_plural = "s waiting for serialization";
    868      1.1  christos 	  tail->suffix_singular = " waiting for serialization";
    869      1.1  christos 	}
    870      1.1  christos 
    871      1.1  christos 	if (model_ptr->nr_stalls_writeback) {
    872      1.1  christos 	  tail->next = ZALLOC(model_print);
    873      1.1  christos 	  tail = tail->next;
    874      1.1  christos 	  tail->count = model_ptr->nr_stalls_writeback;
    875      1.1  christos 	  tail->name = "";
    876      1.1  christos 	  tail->suffix_plural = "times a write-back slot was unavailable";
    877      1.1  christos 	  tail->suffix_singular = "time a writeback was unavailable";
    878      1.1  christos 	}
    879      1.1  christos 
    880      1.1  christos 	if (model_ptr->nr_branches) {
    881      1.1  christos 	  tail->next = ZALLOC(model_print);
    882      1.1  christos 	  tail = tail->next;
    883      1.1  christos 	  tail->count = model_ptr->nr_branches;
    884      1.1  christos 	  tail->name = "branch";
    885      1.1  christos 	  tail->suffix_plural = "es";
    886      1.1  christos 	  tail->suffix_singular = "";
    887      1.1  christos 	}
    888      1.1  christos 
    889      1.1  christos 	if (model_ptr->nr_branches_fallthrough) {
    890      1.1  christos 	  tail->next = ZALLOC(model_print);
    891      1.1  christos 	  tail = tail->next;
    892      1.1  christos 	  tail->count = model_ptr->nr_branches_fallthrough;
    893      1.1  christos 	  tail->name = "conditional branch";
    894      1.1  christos 	  tail->suffix_plural = "es fell through";
    895      1.1  christos 	  tail->suffix_singular = " fell through";
    896      1.1  christos 	}
    897      1.1  christos 
    898      1.1  christos 	if (model_ptr->nr_branch_predict_trues) {
    899      1.1  christos 	  tail->next = ZALLOC(model_print);
    900      1.1  christos 	  tail = tail->next;
    901      1.1  christos 	  tail->count = model_ptr->nr_branch_predict_trues;
    902      1.1  christos 	  tail->name = "successful branch prediction";
    903      1.1  christos 	  tail->suffix_plural = "s";
    904      1.1  christos 	  tail->suffix_singular = "";
    905      1.1  christos 	}
    906      1.1  christos 
    907      1.1  christos 	if (model_ptr->nr_branch_predict_falses) {
    908      1.1  christos 	  tail->next = ZALLOC(model_print);
    909      1.1  christos 	  tail = tail->next;
    910      1.1  christos 	  tail->count = model_ptr->nr_branch_predict_falses;
    911      1.1  christos 	  tail->name = "unsuccessful branch prediction";
    912      1.1  christos 	  tail->suffix_plural = "s";
    913      1.1  christos 	  tail->suffix_singular = "";
    914      1.1  christos 	}
    915      1.1  christos 
    916      1.1  christos 	for (j = 0; j < ARRAY_SIZE (ppc_branch_conditional_name); j++) {
    917      1.1  christos 	  if (model_ptr->nr_branch_conditional[j]) {
    918      1.1  christos 	    tail->next = ZALLOC(model_print);
    919      1.1  christos 	    tail = tail->next;
    920      1.1  christos 	    tail->count = model_ptr->nr_branch_conditional[j];
    921      1.1  christos 	    tail->name = ppc_branch_conditional_name[j];
    922      1.1  christos 	    tail->suffix_plural = " conditional branches";
    923      1.1  christos 	    tail->suffix_singular = " conditional branch";
    924      1.1  christos 	  }
    925      1.1  christos 	}
    926      1.1  christos 
    927      1.1  christos 	for (j = 0; j < 9; j++) {
    928      1.1  christos 	  if (model_ptr->nr_mtcrf_crs[j]) {
    929      1.1  christos 	    tail->next = ZALLOC(model_print);
    930      1.1  christos 	    tail = tail->next;
    931      1.1  christos 	    tail->count = model_ptr->nr_mtcrf_crs[j];
    932      1.1  christos 	    tail->name = ppc_nr_mtcrf_crs[j];
    933      1.1  christos 	    tail->suffix_plural = " instructions";
    934      1.1  christos 	    tail->suffix_singular = " instruction";
    935      1.1  christos 	  }
    936      1.1  christos 	}
    937      1.1  christos 
    938      1.1  christos 	nr_insns = 0;
    939      1.1  christos 	for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
    940      1.1  christos 	  if (model_ptr->nr_units[i]) {
    941      1.1  christos 	    nr_insns += model_ptr->nr_units[i];
    942      1.1  christos 	    tail->next = ZALLOC(model_print);
    943      1.1  christos 	    tail = tail->next;
    944      1.1  christos 	    tail->count = model_ptr->nr_units[i];
    945      1.1  christos 	    tail->name = ppc_function_unit_name[i];
    946      1.1  christos 	    tail->suffix_plural = "s";
    947      1.1  christos 	    tail->suffix_singular = "";
    948      1.1  christos 	  }
    949      1.1  christos 	}
    950      1.1  christos 
    951      1.1  christos 	tail->next = ZALLOC(model_print);
    952      1.1  christos 	tail = tail->next;
    953      1.1  christos 	tail->count = nr_insns;
    954      1.1  christos 	tail->name = "instruction";
    955      1.1  christos 	tail->suffix_plural = "s that were accounted for in timing info";
    956      1.1  christos 	tail->suffix_singular = " that was accounted for in timing info";
    957      1.1  christos 
    958      1.1  christos 	tail->next = (model_print *)0;
    959      1.1  christos 	return head;
    960      1.1  christos 
    961      1.1  christos void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
    962      1.1  christos 	while (ptr) {
    963      1.1  christos 	  model_print *next = ptr->next;
    964      1.1  christos 	  free((void *)ptr);
    965      1.1  christos 	  ptr = next;
    966      1.1  christos 	}
    967      1.1  christos 
    968      1.1  christos void::model-function::model_branches:model_data *model_ptr, int failed, int conditional
    969      1.1  christos 	model_ptr->nr_units[PPC_UNIT_BPU]++;
    970      1.1  christos 	if (failed)
    971      1.1  christos 	  model_ptr->nr_branches_fallthrough++;
    972      1.1  christos 	else
    973      1.1  christos 	  model_ptr->nr_branches++;
    974      1.1  christos 	if (conditional >= 0)
    975      1.1  christos 	  model_ptr->nr_branch_conditional[conditional]++;
    976      1.1  christos 	model_new_cycle(model_ptr);	/* A branch always ends the current cycle */
    977      1.1  christos 
    978      1.1  christos void::model-function::model_branch_predict:model_data *model_ptr, int success
    979      1.1  christos 	if (success)
    980      1.1  christos 	  model_ptr->nr_branch_predict_trues++;
    981      1.1  christos 	else
    982      1.1  christos 	  model_ptr->nr_branch_predict_falses++;
    983      1.1  christos 
    984      1.1  christos 
    986      1.1  christos # The following (illegal) instruction is `known' by gen and is
    987      1.1  christos # called when ever an illegal instruction is encountered
    988      1.1  christos ::internal::illegal
    989      1.1  christos 	program_interrupt(processor, cia,
    990      1.1  christos 	                  illegal_instruction_program_interrupt);
    991      1.1  christos 
    992      1.1  christos 
    993      1.1  christos # The following (floating point unavailable) instruction is `known' by gen
    994      1.1  christos # and is called when ever an a floating point instruction is to be
    995      1.1  christos # executed but floating point is make unavailable by the MSR
    996      1.1  christos ::internal::floating_point_unavailable
    997      1.1  christos 	floating_point_unavailable_interrupt(processor, cia);
    998      1.1  christos 
    999      1.1  christos 
   1000      1.1  christos #
   1001      1.1  christos # Floating point support functions
   1002      1.1  christos #
   1003      1.1  christos 
   1004      1.1  christos # Convert 32bit single to 64bit double
   1005      1.1  christos uint64_t::function::DOUBLE:uint32_t WORD
   1006      1.1  christos 	uint64_t FRT;
   1007      1.1  christos 	if (EXTRACTED32(WORD, 1, 8) > 0
   1008      1.1  christos 	    && EXTRACTED32(WORD, 1, 8) < 255) {
   1009      1.1  christos 	  /* normalized operand */
   1010      1.1  christos 	  int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
   1011      1.1  christos 	  FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
   1012      1.1  christos 	         | INSERTED64(not_word_1_1, 2, 2)
   1013      1.1  christos 	         | INSERTED64(not_word_1_1, 3, 3)
   1014      1.1  christos 	         | INSERTED64(not_word_1_1, 4, 4)
   1015      1.1  christos 	         | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
   1016      1.1  christos 	}
   1017      1.1  christos 	else if (EXTRACTED32(WORD, 1, 8) == 0
   1018      1.1  christos 	         && EXTRACTED32(WORD, 9, 31) != 0) {
   1019      1.1  christos 	  /* denormalized operand */
   1020      1.1  christos 	  int sign = EXTRACTED32(WORD, 0, 0);
   1021      1.1  christos 	  int exp = -126;
   1022      1.1  christos 	  uint64_t frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
   1023      1.1  christos 	  /* normalize the operand */
   1024      1.1  christos 	  while (MASKED64(frac, 0, 0) == 0) {
   1025      1.1  christos 	    frac <<= 1;
   1026      1.1  christos 	    exp -= 1;
   1027      1.1  christos 	  }
   1028      1.1  christos 	  FRT = (INSERTED64(sign, 0, 0)
   1029      1.1  christos 	         | INSERTED64(exp + 1023, 1, 11)
   1030      1.1  christos 	         | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
   1031      1.1  christos 	}
   1032      1.1  christos 	else if (EXTRACTED32(WORD, 1, 8) == 255
   1033      1.1  christos 		 || EXTRACTED32(WORD, 1, 31) == 0) {
   1034      1.1  christos 	  FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
   1035      1.1  christos 	         | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
   1036      1.1  christos 	         | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
   1037      1.1  christos 	         | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
   1038      1.1  christos 	         | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
   1039      1.1  christos 	}
   1040      1.1  christos 	else {
   1041      1.1  christos 	  error("DOUBLE - unknown case\n");
   1042      1.1  christos 	  FRT = 0;
   1043      1.1  christos 	}
   1044      1.1  christos 	return FRT;
   1045      1.1  christos 
   1046      1.1  christos # Convert 64bit single to 32bit double
   1047      1.1  christos uint32_t::function::SINGLE:uint64_t FRS
   1048      1.1  christos 	uint32_t WORD;
   1049      1.1  christos 	if (EXTRACTED64(FRS, 1, 11) > 896
   1050      1.1  christos 	    || EXTRACTED64(FRS, 1, 63) == 0) {
   1051      1.1  christos 	  /* no denormalization required (includes Zero/Infinity/NaN) */
   1052      1.1  christos 	  WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
   1053      1.1  christos 	          | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
   1054      1.1  christos 	}
   1055      1.1  christos 	else if (874 <= EXTRACTED64(FRS, 1, 11)
   1056      1.1  christos 	         && EXTRACTED64(FRS, 1, 11) <= 896) {
   1057      1.1  christos 	  /* denormalization required */
   1058      1.1  christos 	  int sign = EXTRACTED64(FRS, 0, 0);
   1059      1.1  christos 	  int exp = EXTRACTED64(FRS, 1, 11) - 1023;
   1060      1.1  christos 	  uint64_t frac = (BIT64(0)
   1061      1.1  christos 	                     | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
   1062      1.1  christos 	  /* denormalize the operand */
   1063      1.1  christos 	  while (exp < -126) {
   1064      1.1  christos 	    frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
   1065      1.1  christos 	    exp += 1;
   1066      1.1  christos 	  }
   1067      1.1  christos 	  WORD = (INSERTED32(sign, 0, 0)
   1068      1.1  christos 	          | INSERTED32(0x00, 1, 8)
   1069      1.1  christos 	          | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
   1070      1.1  christos 	}
   1071      1.1  christos 	else {
   1072      1.1  christos 	  WORD = 0x0; /* ??? */
   1073      1.1  christos 	}	  
   1074      1.1  christos 	return WORD;
   1075      1.1  christos 
   1076      1.1  christos 
   1077      1.1  christos # round 64bit double to 64bit but single
   1078      1.1  christos void::function::Round_Single:cpu *processor, int sign, int *exp, uint64_t *frac_grx
   1079      1.1  christos 	/* comparisons ignore u bits */
   1080      1.1  christos 	uint64_t out;
   1081      1.1  christos 	int inc = 0;
   1082      1.1  christos 	int lsb = EXTRACTED64(*frac_grx, 23, 23);
   1083      1.1  christos 	int gbit = EXTRACTED64(*frac_grx, 24, 24);
   1084      1.1  christos 	int rbit = EXTRACTED64(*frac_grx, 25, 25);
   1085      1.1  christos 	int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
   1086      1.1  christos 	if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
   1087      1.1  christos 	  if (lsb == 1 && gbit == 1) inc = 1;
   1088      1.1  christos 	  if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
   1089      1.1  christos 	  if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
   1090      1.1  christos 	}
   1091      1.1  christos 	if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
   1092      1.1  christos 	  if (sign == 0 && gbit == 1) inc = 1;
   1093      1.1  christos 	  if (sign == 0 && rbit == 1) inc = 1;
   1094      1.1  christos 	  if (sign == 0 && xbit == 1) inc = 1;
   1095      1.1  christos 	}
   1096      1.1  christos 	if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
   1097      1.1  christos 	  if (sign == 1 && gbit == 1) inc = 1;
   1098      1.1  christos 	  if (sign == 1 && rbit == 1) inc = 1;
   1099      1.1  christos 	  if (sign == 1 && xbit == 1) inc = 1;
   1100      1.1  christos 	}
   1101      1.1  christos 	/* work out addition in low 25 bits of out */
   1102      1.1  christos 	out = EXTRACTED64(*frac_grx, 0, 23) + inc;
   1103      1.1  christos 	*frac_grx = INSERTED64(out, 0, 23);
   1104      1.1  christos 	if (out & BIT64(64 - 23 - 1 - 1)) {
   1105      1.1  christos 	  *frac_grx = (BIT64(0) |
   1106      1.1  christos 	               INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
   1107      1.1  christos 	  *exp = *exp + 1;
   1108      1.1  christos 	}
   1109      1.1  christos 	/* frac_grx[24:52] = 0 already */
   1110      1.1  christos 	FPSCR_SET_FR(inc);
   1111      1.1  christos 	FPSCR_SET_FI(gbit || rbit || xbit);
   1112      1.1  christos 
   1113      1.1  christos 
   1114      1.1  christos #
   1115      1.1  christos void::function::Round_Integer:cpu *processor, int sign, uint64_t *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
   1116      1.1  christos 	int inc = 0;
   1117      1.1  christos 	if (round_mode == fpscr_rn_round_to_nearest) {
   1118      1.1  christos 	  if (*frac64 == 1 && gbit == 1) inc = 1;
   1119      1.1  christos 	  if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
   1120      1.1  christos 	  if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
   1121      1.1  christos 	}
   1122      1.1  christos 	if (round_mode == fpscr_rn_round_towards_pos_infinity) {
   1123      1.1  christos 	  if (sign == 0 && gbit == 1) inc = 1;
   1124      1.1  christos 	  if (sign == 0 && rbit == 1) inc = 1;
   1125      1.1  christos 	  if (sign == 0 && xbit == 1) inc = 1;
   1126      1.1  christos 	}
   1127      1.1  christos 	if (round_mode == fpscr_rn_round_towards_neg_infinity) {
   1128      1.1  christos 	  if (sign == 1 && gbit == 1) inc = 1;
   1129      1.1  christos 	  if (sign == 1 && rbit == 1) inc = 1;
   1130      1.1  christos 	  if (sign == 1 && xbit == 1) inc = 1;
   1131      1.1  christos 	}
   1132      1.1  christos 	/* frac[0:64] = frac[0:64} + inc */
   1133      1.1  christos 	*frac += (*frac64 && inc ? 1 : 0);
   1134      1.1  christos 	*frac64 = (*frac64 + inc) & 0x1;
   1135      1.1  christos 	FPSCR_SET_FR(inc);
   1136      1.1  christos 	FPSCR_SET_FI(gbit | rbit | xbit);
   1137      1.1  christos 
   1138      1.1  christos 
   1139      1.1  christos void::function::Round_Float:cpu *processor, int sign, int *exp, uint64_t *frac, fpscreg round_mode
   1140      1.1  christos 	int carry_out;
   1141      1.1  christos 	int inc = 0;
   1142      1.1  christos 	int lsb = EXTRACTED64(*frac, 52, 52);
   1143      1.1  christos 	int gbit = EXTRACTED64(*frac, 53, 53);
   1144      1.1  christos 	int rbit = EXTRACTED64(*frac, 54, 54);
   1145      1.1  christos 	int xbit = EXTRACTED64(*frac, 55, 55);
   1146      1.1  christos 	if (round_mode == fpscr_rn_round_to_nearest) {
   1147      1.1  christos 	  if (lsb == 1 && gbit == 1) inc = 1;
   1148      1.1  christos 	  if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
   1149      1.1  christos 	  if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
   1150      1.1  christos 	}
   1151      1.1  christos 	if (round_mode == fpscr_rn_round_towards_pos_infinity) {
   1152      1.1  christos 	  if (sign == 0 && gbit == 1) inc = 1;
   1153      1.1  christos 	  if (sign == 0 && rbit == 1) inc = 1;
   1154      1.1  christos 	  if (sign == 0 && xbit == 1) inc = 1;
   1155      1.1  christos 	}
   1156      1.1  christos 	if (round_mode == fpscr_rn_round_towards_neg_infinity) {
   1157      1.1  christos 	  if (sign == 1 && gbit == 1) inc = 1;
   1158      1.1  christos 	  if (sign == 1 && rbit == 1) inc = 1;
   1159      1.1  christos 	  if (sign == 1 && xbit == 1) inc = 1;
   1160      1.1  christos 	}
   1161      1.1  christos 	/* frac//carry_out = frac + inc */
   1162      1.1  christos 	*frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
   1163      1.1  christos 	carry_out = EXTRACTED64(*frac, 0, 0);
   1164      1.1  christos 	*frac <<= 1;
   1165      1.1  christos 	if (carry_out == 1) *exp = *exp + 1;
   1166      1.1  christos 	FPSCR_SET_FR(inc);
   1167      1.1  christos 	FPSCR_SET_FI(gbit | rbit | xbit);
   1168      1.1  christos 	FPSCR_SET_XX(FPSCR & fpscr_fi);
   1169      1.1  christos 
   1170      1.1  christos 
   1171      1.1  christos # conversion of FP to integer
   1172      1.1  christos void::function::convert_to_integer:cpu *processor, unsigned_word cia, uint64_t *frt, uint64_t frb, fpscreg round_mode, int tgt_precision
   1173      1.1  christos 	int i;
   1174      1.1  christos 	int exp = 0;
   1175      1.1  christos 	uint64_t frac = 0;
   1176      1.1  christos 	int frac64 = 0;
   1177      1.1  christos 	int gbit = 0;
   1178      1.1  christos 	int rbit = 0;
   1179      1.1  christos 	int xbit = 0;
   1180      1.1  christos 	int sign = EXTRACTED64(frb, 0, 0);
   1181      1.1  christos 	/***/
   1182      1.1  christos 	  if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
   1183      1.1  christos 	    GOTO(Infinity_Operand);
   1184      1.1  christos 	  if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
   1185      1.1  christos 	    GOTO(SNaN_Operand);
   1186      1.1  christos 	  if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
   1187      1.1  christos 	    GOTO(QNaN_Operand);
   1188      1.1  christos 	  if (EXTRACTED64(frb, 1, 11) > 1086) GOTO(Large_Operand);
   1189      1.1  christos 	  if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
   1190      1.1  christos 	  if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
   1191      1.1  christos 	  if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
   1192      1.1  christos 	    frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
   1193      1.1  christos 	    frac64 = 0;
   1194      1.1  christos 	  }
   1195      1.1  christos 	  if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
   1196      1.1  christos 	    frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
   1197      1.1  christos 	    frac64 = 0;
   1198      1.1  christos 	  }
   1199      1.1  christos 	  gbit = 0, rbit = 0, xbit = 0;
   1200      1.1  christos 	  for (i = 1; i <= 63 - exp; i++) {
   1201      1.1  christos 	    xbit = rbit | xbit;
   1202      1.1  christos 	    rbit = gbit;
   1203      1.1  christos 	    gbit = frac64;
   1204      1.1  christos 	    frac64 = EXTRACTED64(frac, 63, 63);
   1205      1.1  christos 	    frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
   1206      1.1  christos 	  }
   1207      1.1  christos 	  Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
   1208      1.1  christos 	  if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
   1209      1.1  christos 	    frac = ~frac;
   1210      1.1  christos 	    frac64 ^= 1;
   1211      1.1  christos 	    frac += (frac64 ? 1 : 0);
   1212      1.1  christos 	    frac64 = (frac64 + 1) & 0x1;
   1213      1.1  christos 	  }
   1214      1.1  christos 	  if (tgt_precision == 32 /* can ignore frac64 in compare */
   1215      1.1  christos 	      && (int64_t)frac > (int64_t)MASK64(33+1, 63)/*2^31-1 >>1*/)
   1216      1.1  christos 	    GOTO(Large_Operand);
   1217      1.1  christos 	  if (tgt_precision == 64 /* can ignore frac64 in compare */
   1218      1.1  christos 	      && (int64_t)frac > (int64_t)MASK64(1+1, 63)/*2^63-1 >>1*/)
   1219      1.1  christos 	    GOTO(Large_Operand);
   1220      1.1  christos 	  if (tgt_precision == 32 /* can ignore frac64 in compare */
   1221      1.1  christos 	      && (int64_t)frac < (int64_t)MASK64(0, 32+1)/*-2^31 >>1*/)
   1222      1.1  christos 	    GOTO(Large_Operand);
   1223      1.1  christos 	  if (tgt_precision == 64 /* can ignore frac64 in compare */
   1224      1.1  christos 	      && (int64_t)frac < (int64_t)MASK64(0, 0+1)/*-2^63 >>1*/)
   1225      1.1  christos 	    GOTO(Large_Operand);
   1226      1.1  christos 	  FPSCR_SET_XX(FPSCR & fpscr_fi);
   1227      1.1  christos 	  if (tgt_precision == 32)
   1228      1.1  christos 	    *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
   1229      1.1  christos 	  if (tgt_precision == 64)
   1230      1.1  christos 	    *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
   1231      1.1  christos 	  /*FPSCR[fprf] = undefined */
   1232      1.1  christos 	  GOTO(Done);
   1233      1.1  christos 	  /**/
   1234      1.1  christos 	LABEL(Infinity_Operand):
   1235      1.1  christos 	  FPSCR_SET_FR(0);
   1236      1.1  christos 	  FPSCR_SET_FI(0);
   1237      1.1  christos 	  FPSCR_OR_VX(fpscr_vxcvi);
   1238      1.1  christos 	  if ((FPSCR & fpscr_ve) == 0) {
   1239      1.1  christos 	    if (tgt_precision == 32) {
   1240      1.1  christos 	      if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
   1241      1.1  christos 	      if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
   1242      1.1  christos 	    }
   1243      1.1  christos 	    else {
   1244      1.1  christos 	      if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
   1245      1.1  christos 	      if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
   1246      1.1  christos 	    }
   1247      1.1  christos 	    /* FPSCR[FPRF] = undefined */
   1248      1.1  christos 	  }
   1249      1.1  christos 	  GOTO(Done);
   1250      1.1  christos 	/**/
   1251      1.1  christos 	LABEL(SNaN_Operand):
   1252      1.1  christos 	  FPSCR_SET_FR(0);
   1253      1.1  christos 	  FPSCR_SET_FI(0);
   1254      1.1  christos 	  FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
   1255      1.1  christos 	  if ((FPSCR & fpscr_ve) == 0) {
   1256      1.1  christos 	    if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
   1257      1.1  christos 	    if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
   1258      1.1  christos 	    /* FPSCR[fprf] = undefined */
   1259      1.1  christos 	  }
   1260      1.1  christos 	  GOTO(Done);
   1261      1.1  christos 	/**/
   1262      1.1  christos 	LABEL(QNaN_Operand):
   1263      1.1  christos 	  FPSCR_SET_FR(0);
   1264      1.1  christos 	  FPSCR_SET_FI(0);
   1265      1.1  christos 	  FPSCR_OR_VX(fpscr_vxcvi);
   1266      1.1  christos 	  if ((FPSCR & fpscr_ve) == 0) {
   1267      1.1  christos 	    if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
   1268      1.1  christos 	    if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
   1269      1.1  christos 	    /* FPSCR[fprf] = undefined */
   1270      1.1  christos 	  }
   1271      1.1  christos 	  GOTO(Done);
   1272      1.1  christos 	/**/
   1273      1.1  christos 	LABEL(Large_Operand):
   1274      1.1  christos 	  FPSCR_SET_FR(0);
   1275      1.1  christos 	  FPSCR_SET_FI(0);
   1276      1.1  christos 	  FPSCR_OR_VX(fpscr_vxcvi);
   1277      1.1  christos 	  if ((FPSCR & fpscr_ve) == 0) {
   1278      1.1  christos 	    if (tgt_precision == 32) {
   1279      1.1  christos 	      if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
   1280      1.1  christos 	      if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
   1281      1.1  christos 	    }
   1282      1.1  christos 	    else {
   1283      1.1  christos 	      if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
   1284      1.1  christos 	      if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
   1285      1.1  christos 	    }
   1286      1.1  christos 	    /* FPSCR[fprf] = undefined */
   1287      1.1  christos 	  }
   1288      1.1  christos 	/**/
   1289      1.1  christos 	LABEL(Done):;
   1290      1.1  christos 
   1291      1.1  christos 
   1292      1.1  christos # extract out raw fields of a FP number
   1293      1.1  christos int::function::sign:uint64_t FRS
   1294      1.1  christos 	return (MASKED64(FRS, 0, 0)
   1295      1.1  christos 	        ? -1
   1296      1.1  christos 	        : 1);
   1297      1.1  christos int::function::biased_exp:uint64_t frs, int single
   1298      1.1  christos 	if (single)
   1299      1.1  christos 	  return EXTRACTED64(frs, 1, 8);
   1300      1.1  christos 	else
   1301      1.1  christos 	  return EXTRACTED64(frs, 1, 11);
   1302      1.1  christos uint64_t::function::fraction:uint64_t frs, int single
   1303      1.1  christos 	if (single)
   1304      1.1  christos 	  return EXTRACTED64(frs, 9, 31);
   1305      1.1  christos 	else
   1306      1.1  christos 	  return EXTRACTED64(frs, 12, 63);
   1307      1.1  christos 
   1308      1.1  christos # a number?, each of the below return +1 or -1 (based on sign bit)
   1309      1.1  christos # if true.
   1310      1.1  christos int::function::is_nor:uint64_t frs, int single
   1311      1.1  christos 	int exp = biased_exp(frs, single);
   1312      1.1  christos 	return (exp >= 1
   1313      1.1  christos 	        && exp <= (single ? 254 : 2046));
   1314      1.1  christos int::function::is_zero:uint64_t FRS
   1315      1.1  christos 	return (MASKED64(FRS, 1, 63) == 0
   1316      1.1  christos 	        ? sign(FRS)
   1317      1.1  christos 	        : 0);
   1318      1.1  christos int::function::is_den:uint64_t frs, int single
   1319      1.1  christos 	int exp = biased_exp(frs, single);
   1320      1.1  christos 	uint64_t frac = fraction(frs, single);
   1321      1.1  christos 	return (exp == 0 && frac != 0
   1322      1.1  christos 	        ? sign(frs)
   1323      1.1  christos 	        : 0);
   1324      1.1  christos int::function::is_inf:uint64_t frs, int single
   1325      1.1  christos 	int exp = biased_exp(frs, single);
   1326      1.1  christos 	uint64_t frac = fraction(frs, single);
   1327      1.1  christos 	return (exp == (single ? 255 : 2047) && frac == 0
   1328      1.1  christos 	        ? sign(frs)
   1329      1.1  christos 	        : 0);
   1330      1.1  christos int::function::is_NaN:uint64_t frs, int single
   1331      1.1  christos 	int exp = biased_exp(frs, single);
   1332      1.1  christos 	uint64_t frac = fraction(frs, single);
   1333      1.1  christos 	return (exp == (single ? 255 : 2047) && frac != 0
   1334      1.1  christos 	        ? sign(frs)
   1335      1.1  christos 	        : 0);
   1336      1.1  christos int::function::is_SNaN:uint64_t frs, int single
   1337      1.1  christos 	return (is_NaN(frs, single)
   1338      1.1  christos 	        && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
   1339      1.1  christos 	             ? sign(frs)
   1340      1.1  christos 	             : 0);
   1341      1.1  christos int::function::is_QNaN:uint64_t frs, int single
   1342      1.1  christos 	return (is_NaN(frs, single) && !is_SNaN(frs, single));
   1343      1.1  christos int::function::is_less_than:uint64_t *fra, uint64_t *frb
   1344      1.1  christos 	return *(double*)fra < *(double*)frb;
   1345      1.1  christos int::function::is_greater_than:uint64_t *fra, uint64_t *frb
   1346      1.1  christos 	return *(double*)fra > *(double*)frb;
   1347      1.1  christos int::function::is_equan_to:uint64_t *fra, uint64_t *frb
   1348      1.1  christos 	return *(double*)fra == *(double*)frb;
   1349      1.1  christos 
   1350      1.1  christos 
   1351      1.1  christos # which quiet nan should become the result
   1352      1.1  christos uint64_t::function::select_qnan:uint64_t fra, uint64_t frb, uint64_t frc, int instruction_is_frsp, int generate_qnan, int single
   1353      1.1  christos 	uint64_t frt = 0;
   1354      1.1  christos 	if (is_NaN(fra, single))
   1355      1.1  christos 	  frt = fra;
   1356      1.1  christos 	else if (is_NaN(frb, single))
   1357      1.1  christos 	  if (instruction_is_frsp)
   1358      1.1  christos 	    frt = MASKED64(frb, 0, 34);
   1359      1.1  christos 	  else
   1360      1.1  christos 	    frt = frb;
   1361      1.1  christos 	else if (is_NaN(frc, single))
   1362      1.1  christos 	  frt = frc;
   1363      1.1  christos 	else if (generate_qnan)
   1364      1.1  christos 	  frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
   1365      1.1  christos 	else
   1366      1.1  christos 	  error("select_qnan - default reached\n");
   1367      1.1  christos 	return frt;
   1368      1.1  christos 
   1369      1.1  christos 
   1370      1.1  christos # detect invalid operation
   1371      1.1  christos int::function::is_invalid_operation:cpu *processor, unsigned_word cia, uint64_t fra, uint64_t frb, fpscreg check, int single, int negate
   1372      1.1  christos 	int fail = 0;
   1373      1.1  christos 	if ((check & fpscr_vxsnan)
   1374      1.1  christos 	    && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
   1375      1.1  christos 	  FPSCR_OR_VX(fpscr_vxsnan);
   1376      1.1  christos 	  fail = 1;
   1377      1.1  christos 	}
   1378      1.1  christos 	if ((check & fpscr_vxisi)
   1379      1.1  christos 	    && (is_inf(fra, single) && is_inf(frb, single))
   1380      1.1  christos 	    && ((negate && sign(fra) != sign(frb))
   1381      1.1  christos 	        || (!negate && sign(fra) == sign(frb)))) {
   1382      1.1  christos 	   /*FIXME: don't handle inf-inf VS inf+-inf */
   1383      1.1  christos 	  FPSCR_OR_VX(fpscr_vxisi);
   1384      1.1  christos 	  fail = 1;
   1385      1.1  christos 	}
   1386      1.1  christos 	if ((check & fpscr_vxidi)
   1387      1.1  christos 	    && (is_inf(fra, single) && is_inf(frb, single))) {
   1388      1.1  christos 	  FPSCR_OR_VX(fpscr_vxidi);
   1389      1.1  christos 	  fail = 1;
   1390      1.1  christos 	}
   1391      1.1  christos 	if ((check & fpscr_vxzdz)
   1392      1.1  christos 	    && (is_zero(fra) && is_zero(frb))) {
   1393      1.1  christos 	  FPSCR_OR_VX(fpscr_vxzdz);
   1394      1.1  christos 	  fail = 1;
   1395      1.1  christos 	}
   1396      1.1  christos 	if ((check & fpscr_vximz)
   1397      1.1  christos 	    && (is_zero(fra) && is_inf(frb, single))) {
   1398      1.1  christos 	  FPSCR_OR_VX(fpscr_vximz);
   1399      1.1  christos 	  fail = 1;
   1400      1.1  christos 	}
   1401      1.1  christos 	if ((check & fpscr_vxvc)
   1402      1.1  christos 	    && (is_NaN(fra, single) || is_NaN(frb, single))) {
   1403      1.1  christos 	  FPSCR_OR_VX(fpscr_vxvc);
   1404      1.1  christos 	  fail = 1;
   1405      1.1  christos 	}
   1406      1.1  christos 	if ((check & fpscr_vxsoft)) {
   1407      1.1  christos 	  FPSCR_OR_VX(fpscr_vxsoft);
   1408      1.1  christos 	  fail = 1;
   1409      1.1  christos 	}
   1410      1.1  christos 	if ((check & fpscr_vxsqrt)
   1411      1.1  christos 	    && sign(fra) < 0) {
   1412      1.1  christos 	  FPSCR_OR_VX(fpscr_vxsqrt);
   1413      1.1  christos 	  fail = 1;
   1414      1.1  christos 	}
   1415      1.1  christos 	/* if ((check && fpscr_vxcvi) {
   1416      1.1  christos 	    && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
   1417      1.1  christos 	  FPSCR_OR_VX(fpscr_vxcvi);
   1418      1.1  christos 	  fail = 1;
   1419      1.1  christos 	}
   1420      1.1  christos 	*/
   1421      1.1  christos 	return fail;
   1422      1.1  christos 
   1423      1.1  christos 
   1424      1.1  christos 
   1425      1.1  christos 
   1426      1.1  christos 
   1427      1.1  christos # handle case of invalid operation
   1428      1.1  christos void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, uint64_t *frt, uint64_t fra, uint64_t frb, uint64_t frc, int instruction_is_frsp, int instruction_is_convert_to_64bit, int instruction_is_convert_to_32bit, int single
   1429      1.1  christos 	if (FPSCR & fpscr_ve) {
   1430      1.1  christos 	  /* invalid operation exception enabled */
   1431      1.1  christos 	  /* FRT unchaged */
   1432      1.1  christos 	  FPSCR_SET_FR(0);
   1433      1.1  christos 	  FPSCR_SET_FI(0);
   1434      1.1  christos 	  /* fpscr_FPRF unchanged */
   1435      1.1  christos 	}
   1436      1.1  christos 	else {
   1437      1.1  christos 	  /* invalid operation exception disabled */
   1438      1.1  christos 	  if (instruction_is_convert_to_64bit) {
   1439      1.1  christos 	    error("oopsi");
   1440      1.1  christos 	  }
   1441      1.1  christos 	  else if (instruction_is_convert_to_32bit) {
   1442      1.1  christos 	    error("oopsi");
   1443      1.1  christos 	  }
   1444      1.1  christos 	  else { /* arrith, frsp */
   1445      1.1  christos 	    *frt = select_qnan(fra, frb, frc,
   1446      1.1  christos 	                       instruction_is_frsp, 1/*generate*/, single);
   1447      1.1  christos 	    FPSCR_SET_FR(0);
   1448      1.1  christos 	    FPSCR_SET_FI(0);
   1449      1.1  christos 	    FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
   1450      1.1  christos 	  }
   1451      1.1  christos 	}
   1452      1.1  christos 
   1453      1.1  christos 
   1454      1.1  christos 
   1455      1.1  christos 
   1456      1.1  christos # detect divide by zero
   1457      1.1  christos int::function::is_invalid_zero_divide:cpu *processor, unsigned_word cia, uint64_t fra, uint64_t frb, int single
   1458      1.1  christos 	int fail = 0;
   1459      1.1  christos 	if (is_zero (frb)) {
   1460      1.1  christos 	  FPSCR_SET_ZX (1);
   1461      1.1  christos 	  fail = 1;
   1462      1.1  christos 	}
   1463      1.1  christos 	return fail;
   1464      1.1  christos 
   1465      1.1  christos 
   1466      1.1  christos 
   1467      1.1  christos 
   1468      1.1  christos # handle case of invalid operation
   1469      1.1  christos void::function::invalid_zero_divide_operation:cpu *processor, unsigned_word cia, uint64_t *frt, uint64_t fra, uint64_t frb, int single
   1470      1.1  christos 	if (FPSCR & fpscr_ze) {
   1471      1.1  christos 	  /* zero-divide exception enabled */
   1472      1.1  christos 	  /* FRT unchaged */
   1473      1.1  christos 	  FPSCR_SET_FR(0);
   1474      1.1  christos 	  FPSCR_SET_FI(0);
   1475      1.1  christos 	  /* fpscr_FPRF unchanged */
   1476      1.1  christos 	}
   1477      1.1  christos 	else {
   1478      1.1  christos 	  /* zero-divide exception disabled */
   1479      1.1  christos 	  FPSCR_SET_FR(0);
   1480      1.1  christos 	  FPSCR_SET_FI(0);
   1481      1.1  christos 	  if ((sign (fra) < 0 && sign (frb) < 0)
   1482      1.1  christos 	      || (sign (fra) > 0 && sign (frb) > 0)) {
   1483      1.1  christos 	    *frt = MASK64 (1, 11); /* 0 : 2047 : 0..0 */
   1484      1.1  christos 	    FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
   1485      1.1  christos 	  }
   1486      1.1  christos 	  else {
   1487      1.1  christos 	    *frt = MASK64 (0, 11); /* 1 : 2047 : 0..0 */
   1488      1.1  christos 	    FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
   1489      1.1  christos 	  }
   1490      1.1  christos 	}
   1491      1.1  christos 
   1492      1.1  christos 
   1493      1.1  christos 
   1494      1.1  christos 
   1495      1.1  christos 
   1496      1.1  christos #
   1497      1.1  christos # 0.0.0.0 Illegal instruction used for kernel mode emulation
   1498      1.1  christos #
   1499      1.1  christos 0.0,6./,11./,16./,21./,31.1:X:::instruction_call
   1500      1.1  christos 	if (!os_emul_instruction_call(processor, cia, real_addr(cia, 1)))
   1501      1.1  christos 	  program_interrupt(processor, cia,
   1502      1.1  christos 	                    illegal_instruction_program_interrupt);
   1503      1.1  christos 
   1504      1.1  christos #
   1505      1.1  christos # I.2.4.1 Branch Instructions
   1506      1.1  christos #
   1507      1.1  christos 0.18,6.LI,30.AA,31.LK:I:::Branch
   1508      1.1  christos *601: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1509      1.1  christos *603: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1510      1.1  christos *603e:PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1511      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1512      1.1  christos 	/* option_mpc860c0:
   1513      1.1  christos 	No problem here because this branch is predicted taken (unconditional). */
   1514      1.1  christos 	if (AA) NIA = IEA(EXTS(LI_0b00));
   1515      1.1  christos 	else    NIA = IEA(CIA + EXTS(LI_0b00));
   1516      1.1  christos 	if (LK) LR = (spreg)CIA+4;
   1517      1.1  christos 	if (CURRENT_MODEL_ISSUE > 0)
   1518      1.1  christos 	  model_branches(cpu_model(processor), 1, -1);
   1519      1.1  christos 
   1520      1.1  christos 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:::Branch Conditional
   1521      1.1  christos *601: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1522      1.1  christos *603: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1523      1.1  christos *603e:PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1524      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1525      1.1  christos 	int M, ctr_ok, cond_ok, succeed;
   1526      1.1  christos 	if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
   1527      1.1  christos 	  model_wait_for_cr(cpu_model(processor), BIT32_BI);
   1528      1.1  christos 	if (is_64bit_implementation && is_64bit_mode) M = 0;
   1529      1.1  christos 	else                                          M = 32;
   1530      1.1  christos 	if (!BO{2}) CTR = CTR - 1;
   1531      1.1  christos 	ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
   1532      1.1  christos 	cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
   1533      1.1  christos 	if (ctr_ok && cond_ok) {
   1534      1.1  christos 	  if (AA) NIA = IEA(EXTS(BD_0b00));
   1535      1.1  christos 	  else    NIA = IEA(CIA + EXTS(BD_0b00));
   1536      1.1  christos 	  succeed = 1;
   1537      1.1  christos 	}
   1538      1.1  christos 	else
   1539      1.1  christos 	  succeed = 0;
   1540      1.1  christos 	if (LK) LR = (spreg)IEA(CIA + 4);
   1541      1.1  christos 	if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
   1542      1.1  christos 	  /* This branch is predicted as "normal".
   1543      1.1  christos 	  If this is a forward branch and it is near the end of a page,
   1544      1.1  christos 	  we've detected a problematic branch. */
   1545      1.1  christos 	  if (succeed && NIA > CIA) {
   1546      1.1  christos 	    if (MPC860C0_PAGE_SIZE - (CIA & (MPC860C0_PAGE_SIZE-1)) <= option_mpc860c0)
   1547      1.1  christos 	      program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt);
   1548      1.1  christos 	  }
   1549      1.1  christos 	}
   1550      1.1  christos 	if (CURRENT_MODEL_ISSUE > 0)
   1551      1.1  christos 	  model_branches(cpu_model(processor), succeed, BO);
   1552      1.1  christos 	if (! BO{0}) {
   1553      1.1  christos 	  int reverse;
   1554      1.1  christos 	  if (BO{4}) {	/* branch prediction bit set, reverse sense of test */
   1555      1.1  christos 	    reverse = EXTS(BD_0b00) < 0;
   1556      1.1  christos 	  } else {	/* branch prediction bit not set */
   1557      1.1  christos 	    reverse = EXTS(BD_0b00) >= 0;
   1558      1.1  christos 	  }
   1559      1.1  christos 	  if (CURRENT_MODEL_ISSUE > 0)
   1560      1.1  christos 	    model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
   1561      1.1  christos 	}
   1562      1.1  christos 
   1563      1.1  christos 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:::Branch Conditional to Link Register
   1564      1.1  christos *601: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1565      1.1  christos *603: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1566      1.1  christos *603e:PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1567      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1568      1.1  christos 	int M, ctr_ok, cond_ok, succeed;
   1569      1.1  christos 	if (is_64bit_implementation && is_64bit_mode) M = 0;
   1570      1.1  christos 	else                                          M = 32;
   1571      1.1  christos 	if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
   1572      1.1  christos 	  model_wait_for_cr(cpu_model(processor), BIT32_BI);
   1573      1.1  christos 	if (!BO{2}) CTR = CTR - 1;
   1574      1.1  christos 	ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
   1575      1.1  christos 	cond_ok = BO{0} || (CR{BI} == BO{1});
   1576      1.1  christos 	if (ctr_ok && cond_ok) {
   1577      1.1  christos 	  NIA = IEA(LR_0b00);
   1578      1.1  christos 	  succeed = 1;
   1579      1.1  christos 	}
   1580      1.1  christos 	else
   1581      1.1  christos 	  succeed = 0;
   1582      1.1  christos 	if (LK) LR = (spreg)IEA(CIA + 4);
   1583      1.1  christos 	if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
   1584      1.1  christos 	  /* This branch is predicted as not-taken.
   1585      1.1  christos 	  If this is a forward branch and it is near the end of a page,
   1586      1.1  christos 	  we've detected a problematic branch. */
   1587      1.1  christos 	  if (succeed && NIA > CIA) {
   1588      1.1  christos 	    if (MPC860C0_PAGE_SIZE - (CIA & (MPC860C0_PAGE_SIZE-1)) <= option_mpc860c0)
   1589      1.1  christos 	      program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt);
   1590      1.1  christos 	  }
   1591      1.1  christos 	}
   1592      1.1  christos 	if (CURRENT_MODEL_ISSUE > 0) {
   1593      1.1  christos 	  model_branches(cpu_model(processor), succeed, BO);
   1594      1.1  christos 	  if (! BO{0})
   1595      1.1  christos 	    model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
   1596      1.1  christos 	}
   1597      1.1  christos 
   1598      1.1  christos 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:::Branch Conditional to Count Register
   1599      1.1  christos *601: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1600      1.1  christos *603: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1601      1.1  christos *603e:PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1602      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1603      1.1  christos 	int cond_ok, succeed;
   1604      1.1  christos 	if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
   1605      1.1  christos 	  model_wait_for_cr(cpu_model(processor), BIT32_BI);
   1606      1.1  christos 	cond_ok = BO{0} || (CR{BI} == BO{1});
   1607      1.1  christos 	if (cond_ok) {
   1608      1.1  christos 	  NIA = IEA(CTR_0b00);
   1609      1.1  christos 	  succeed = 1;
   1610      1.1  christos 	}
   1611      1.1  christos 	else
   1612      1.1  christos 	  succeed = 0;
   1613      1.1  christos 	if (LK) LR = (spreg)IEA(CIA + 4);
   1614      1.1  christos 	if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
   1615      1.1  christos 	  /* This branch is predicted as not-taken.
   1616      1.1  christos 	  If this is a forward branch and it is near the end of a page,
   1617      1.1  christos 	  we've detected a problematic branch. */
   1618      1.1  christos 	  if (succeed && NIA > CIA) {
   1619      1.1  christos 	    if (MPC860C0_PAGE_SIZE - (CIA & (MPC860C0_PAGE_SIZE-1)) <= option_mpc860c0)
   1620      1.1  christos 	      program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt);
   1621      1.1  christos 	  }
   1622      1.1  christos 	}
   1623      1.1  christos 	if (CURRENT_MODEL_ISSUE > 0) {
   1624      1.1  christos 	  model_branches(cpu_model(processor), succeed, BO);
   1625      1.1  christos 	  if (! BO{0})
   1626      1.1  christos 	    model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
   1627      1.1  christos 	}
   1628      1.1  christos 
   1629      1.1  christos #
   1630      1.1  christos # I.2.4.2 System Call Instruction
   1631      1.1  christos #
   1632      1.1  christos 0.17,6./,11./,16./,30.1,31./:SC:::System Call
   1633      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1634      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
   1635      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
   1636      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   1637      1.1  christos 	if (CURRENT_MODEL_ISSUE > 0)
   1638      1.1  christos 	  model_serialize(MY_INDEX, cpu_model(processor));
   1639      1.1  christos 	system_call_interrupt(processor, cia);
   1640      1.1  christos 
   1641      1.1  christos #
   1642      1.1  christos # I.2.4.3 Condition Register Logical Instructions
   1643      1.1  christos #
   1644      1.1  christos 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
   1645      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1646      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1647      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1648      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1649      1.1  christos 	BLIT32(CR, BT, CR{BA} && CR{BB});
   1650      1.1  christos 	PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
   1651      1.1  christos 
   1652      1.1  christos 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
   1653      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1654      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1655      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1656      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1657      1.1  christos 	BLIT32(CR, BT, CR{BA} || CR{BB});
   1658      1.1  christos 	PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
   1659      1.1  christos 
   1660      1.1  christos 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
   1661      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1662      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1663      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1664      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1665      1.1  christos 	BLIT32(CR, BT, CR{BA} != CR{BB});
   1666      1.1  christos 	PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
   1667      1.1  christos 
   1668      1.1  christos 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
   1669      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1670      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1671      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1672      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1673      1.1  christos 	BLIT32(CR, BT, !(CR{BA} && CR{BB}));
   1674      1.1  christos 	PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
   1675      1.1  christos 
   1676      1.1  christos 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
   1677      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1678      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1679      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1680      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1681      1.1  christos 	BLIT32(CR, BT, !(CR{BA} || CR{BB}));
   1682      1.1  christos 	PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
   1683      1.1  christos 
   1684      1.1  christos 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
   1685      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1686      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1687      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1688      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1689      1.1  christos 	BLIT32(CR, BT, CR{BA} == CR{BB});
   1690      1.1  christos 	PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
   1691      1.1  christos 
   1692      1.1  christos 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
   1693      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1694      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1695      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1696      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1697      1.1  christos 	BLIT32(CR, BT, CR{BA} && !CR{BB});
   1698      1.1  christos 	PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
   1699      1.1  christos 
   1700      1.1  christos 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
   1701      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1702      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1703      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1704      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1705      1.1  christos 	BLIT32(CR, BT, CR{BA} || !CR{BB});
   1706      1.1  christos 	PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
   1707      1.1  christos 
   1708      1.1  christos #
   1709      1.1  christos # I.2.4.4 Condition Register Field Instruction
   1710      1.1  christos #
   1711      1.1  christos 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
   1712      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   1713      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1714      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   1715      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
   1716      1.1  christos 	MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
   1717      1.1  christos 	PPC_INSN_CR(BF_BITMASK, 1 << BFA);
   1718      1.1  christos 
   1719      1.1  christos 
   1720      1.1  christos #
   1721      1.1  christos # I.3.3.2 Fixed-Point Load Instructions
   1722      1.1  christos #
   1723      1.1  christos 
   1724      1.1  christos 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
   1725      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1726      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1727      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1728      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1729      1.1  christos 	unsigned_word b;
   1730      1.1  christos 	unsigned_word EA;
   1731      1.1  christos 	if (RA_is_0) b = 0;
   1732      1.1  christos 	else         b = *rA;
   1733      1.1  christos 	EA = b + EXTS(D);
   1734      1.1  christos 	*rT = MEM(unsigned, EA, 1);
   1735      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
   1736      1.1  christos 
   1737      1.1  christos 
   1738      1.1  christos 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
   1739      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1740      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1741      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1742      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1743      1.1  christos 	unsigned_word b;
   1744      1.1  christos 	unsigned_word EA;
   1745      1.1  christos 	if (RA_is_0) b = 0;
   1746      1.1  christos 	else         b = *rA;
   1747      1.1  christos 	EA = b + *rB;
   1748      1.1  christos 	*rT = MEM(unsigned, EA, 1);
   1749      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   1750      1.1  christos 
   1751      1.1  christos 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
   1752      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1753      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1754      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1755      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1756      1.1  christos 	unsigned_word EA;
   1757      1.1  christos 	if (RA_is_0 || RA == RT)
   1758      1.1  christos 	  program_interrupt(processor, cia,
   1759      1.1  christos 	                    illegal_instruction_program_interrupt);
   1760      1.1  christos 	EA = *rA + EXTS(D);
   1761      1.1  christos 	*rT = MEM(unsigned, EA, 1);
   1762      1.1  christos 	*rA = EA;
   1763      1.1  christos 	PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
   1764      1.1  christos 
   1765      1.1  christos 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
   1766      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1767      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1768      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1769      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1770      1.1  christos 	unsigned_word EA;
   1771      1.1  christos 	if (RA_is_0 || RA == RT)
   1772      1.1  christos 	  program_interrupt(processor, cia,
   1773      1.1  christos 	                    illegal_instruction_program_interrupt);
   1774      1.1  christos 	EA = *rA + *rB;
   1775      1.1  christos 	*rT = MEM(unsigned, EA, 1);
   1776      1.1  christos 	*rA = EA;
   1777      1.1  christos 	PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
   1778      1.1  christos 
   1779      1.1  christos 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
   1780      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1781      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1782      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1783      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1784      1.1  christos 	unsigned_word b;
   1785      1.1  christos 	unsigned_word EA;
   1786      1.1  christos 	if (RA_is_0) b = 0;
   1787      1.1  christos 	else         b = *rA;
   1788      1.1  christos 	EA = b + EXTS(D);
   1789      1.1  christos 	*rT = MEM(unsigned, EA, 2);
   1790      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
   1791      1.1  christos 
   1792      1.1  christos 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
   1793      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1794      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1795      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1796      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1797      1.1  christos 	unsigned_word b;
   1798      1.1  christos 	unsigned_word EA;
   1799      1.1  christos 	if (RA_is_0) b = 0;
   1800      1.1  christos 	else         b = *rA;
   1801      1.1  christos 	EA = b + *rB;
   1802      1.1  christos 	*rT = MEM(unsigned, EA, 2);
   1803      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   1804      1.1  christos 
   1805      1.1  christos 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
   1806      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1807      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1808      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1809      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1810      1.1  christos 	unsigned_word EA;
   1811      1.1  christos 	if (RA_is_0 || RA == RT)
   1812      1.1  christos 	  program_interrupt(processor, cia,
   1813      1.1  christos 	                    illegal_instruction_program_interrupt);
   1814      1.1  christos 	EA = *rA + EXTS(D);
   1815      1.1  christos 	*rT = MEM(unsigned, EA, 2);
   1816      1.1  christos 	*rA = EA;
   1817      1.1  christos 	PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
   1818      1.1  christos 
   1819      1.1  christos 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
   1820      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1821      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1822      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1823      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1824      1.1  christos 	unsigned_word EA;
   1825      1.1  christos 	if (RA_is_0 || RA == RT)
   1826      1.1  christos 	  program_interrupt(processor, cia,
   1827      1.1  christos 	                    illegal_instruction_program_interrupt);
   1828      1.1  christos 	EA = *rA + *rB;
   1829      1.1  christos 	*rT = MEM(unsigned, EA, 2);
   1830      1.1  christos 	*rA = EA;
   1831      1.1  christos 	PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
   1832      1.1  christos 
   1833      1.1  christos 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
   1834      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1835      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1836      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1837      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1838      1.1  christos 	unsigned_word b;
   1839      1.1  christos 	unsigned_word EA;
   1840      1.1  christos 	if (RA_is_0) b = 0;
   1841      1.1  christos 	else         b = *rA;
   1842      1.1  christos 	EA = b + EXTS(D);
   1843      1.1  christos 	*rT = MEM(signed, EA, 2);
   1844      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
   1845      1.1  christos 
   1846      1.1  christos 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
   1847      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1848      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1849      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1850      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1851      1.1  christos 	unsigned_word b;
   1852      1.1  christos 	unsigned_word EA;
   1853      1.1  christos 	if (RA_is_0) b = 0;
   1854      1.1  christos 	else         b = *rA;
   1855      1.1  christos 	EA = b + *rB;
   1856      1.1  christos 	*rT = MEM(signed, EA, 2);
   1857      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   1858      1.1  christos 
   1859      1.1  christos 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
   1860      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1861      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1862      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1863      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1864      1.1  christos 	unsigned_word EA;
   1865      1.1  christos 	if (RA_is_0 || RA == RT)
   1866      1.1  christos 	  program_interrupt(processor, cia,
   1867      1.1  christos 	                    illegal_instruction_program_interrupt);
   1868      1.1  christos 	EA = *rA + EXTS(D);
   1869      1.1  christos 	*rT = MEM(signed, EA, 2);
   1870      1.1  christos 	*rA = EA;
   1871      1.1  christos 	PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
   1872      1.1  christos 
   1873      1.1  christos 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
   1874      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1875      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1876      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1877      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1878      1.1  christos 	unsigned_word EA;
   1879      1.1  christos 	if (RA_is_0 || RA == RT)
   1880      1.1  christos 	  program_interrupt(processor, cia,
   1881      1.1  christos 	                    illegal_instruction_program_interrupt);
   1882      1.1  christos 	EA = *rA + *rB;
   1883      1.1  christos 	*rT = MEM(signed, EA, 2);
   1884      1.1  christos 	*rA = EA;
   1885      1.1  christos 	PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
   1886      1.1  christos 
   1887      1.1  christos 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
   1888      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1889      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1890      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1891      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1892      1.1  christos 	unsigned_word b;
   1893      1.1  christos 	unsigned_word EA;
   1894      1.1  christos 	if (RA_is_0) b = 0;
   1895      1.1  christos 	else         b = *rA;
   1896      1.1  christos 	EA = b + EXTS(D);
   1897      1.1  christos 	*rT = MEM(unsigned, EA, 4);
   1898      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
   1899      1.1  christos 
   1900      1.1  christos 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
   1901      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1902      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1903      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1904      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1905      1.1  christos 	unsigned_word b;
   1906      1.1  christos 	unsigned_word EA;
   1907      1.1  christos 	if (RA_is_0) b = 0;
   1908      1.1  christos 	else         b = *rA;
   1909      1.1  christos 	EA = b + *rB;
   1910      1.1  christos 	*rT = MEM(unsigned, EA, 4);
   1911      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   1912      1.1  christos 
   1913      1.1  christos 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
   1914      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1915      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1916      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1917      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1918      1.1  christos 	unsigned_word EA;
   1919      1.1  christos 	if (RA_is_0 || RA == RT)
   1920      1.1  christos 	  program_interrupt(processor, cia,
   1921      1.1  christos 	                    illegal_instruction_program_interrupt);
   1922      1.1  christos 	EA = *rA + EXTS(D);
   1923      1.1  christos 	*rT = MEM(unsigned, EA, 4);
   1924      1.1  christos 	*rA = EA;
   1925      1.1  christos 	PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
   1926      1.1  christos 
   1927      1.1  christos 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
   1928      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  2,  0
   1929      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1930      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1931      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   1932      1.1  christos 	unsigned_word EA;
   1933      1.1  christos 	if (RA_is_0 || RA == RT)
   1934      1.1  christos 	  program_interrupt(processor, cia,
   1935      1.1  christos 	                    illegal_instruction_program_interrupt);
   1936      1.1  christos 	EA = *rA + *rB;
   1937      1.1  christos 	*rT = MEM(unsigned, EA, 4);
   1938      1.1  christos 	*rA = EA;
   1939      1.1  christos 	PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
   1940      1.1  christos 
   1941      1.1  christos 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
   1942      1.1  christos #	unsigned_word b;
   1943      1.1  christos #	unsigned_word EA;
   1944      1.1  christos #	if (RA_is_0) b = 0;
   1945      1.1  christos #	else         b = *rA;
   1946      1.1  christos #	EA = b + EXTS(DS_0b00);
   1947      1.1  christos #	*rT = MEM(signed, EA, 4);
   1948      1.1  christos 
   1949      1.1  christos 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
   1950      1.1  christos #	unsigned_word b;
   1951      1.1  christos #	unsigned_word EA;
   1952      1.1  christos #	if (RA_is_0) b = 0;
   1953      1.1  christos #	else         b = *rA;
   1954      1.1  christos #	EA = b + *rB;;
   1955      1.1  christos #	*rT = MEM(signed, EA, 4);
   1956      1.1  christos 
   1957      1.1  christos 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
   1958      1.1  christos #	unsigned_word EA;
   1959      1.1  christos #	if (RA_is_0 || RA == RT)
   1960      1.1  christos #	  program_interrupt(processor, cia
   1961      1.1  christos #	                    illegal_instruction_program_interrupt);
   1962      1.1  christos #	EA = *rA + *rB;
   1963      1.1  christos #	*rT = MEM(signed, EA, 4);
   1964      1.1  christos #	*rA = EA;
   1965      1.1  christos 
   1966      1.1  christos 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
   1967      1.1  christos #	unsigned_word b;
   1968      1.1  christos #	unsigned_word EA;
   1969      1.1  christos #	if (RA_is_0) b = 0;
   1970      1.1  christos #	else         b = *rA;
   1971      1.1  christos #	EA = b + EXTS(DS_0b00);
   1972      1.1  christos #	*rT = MEM(unsigned, EA, 8);
   1973      1.1  christos 
   1974      1.1  christos 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
   1975      1.1  christos #	unsigned_word b;
   1976      1.1  christos #	unsigned_word EA;
   1977      1.1  christos #	if (RA_is_0) b = 0;
   1978      1.1  christos #	else         b = *rA;
   1979      1.1  christos #	EA = b + *rB;
   1980      1.1  christos #	*rT = MEM(unsigned, EA, 8);
   1981      1.1  christos 
   1982      1.1  christos 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
   1983      1.1  christos #	unsigned_word EA;
   1984      1.1  christos #	if (RA_is_0 || RA == RT)
   1985      1.1  christos #	  program_interrupt(processor, cia
   1986      1.1  christos #	                    illegal_instruction_program_interrupt);
   1987      1.1  christos #	EA = *rA + EXTS(DS_0b00);
   1988      1.1  christos #	*rT = MEM(unsigned, EA, 8);
   1989      1.1  christos #	*rA = EA;
   1990      1.1  christos 
   1991      1.1  christos 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
   1992      1.1  christos #	unsigned_word EA;
   1993      1.1  christos #	if (RA_is_0 || RA == RT)
   1994      1.1  christos #	  program_interrupt(processor, cia
   1995      1.1  christos #	                    illegal_instruction_program_interrupt);
   1996      1.1  christos #	EA = *rA + *rB;
   1997      1.1  christos #	*rT = MEM(unsigned, EA, 8);
   1998      1.1  christos #	*rA = EA;
   1999      1.1  christos 
   2000      1.1  christos 
   2001      1.1  christos 
   2002      1.1  christos #
   2003      1.1  christos # I.3.3.3 Fixed-Point Store Instructions
   2004      1.1  christos #
   2005      1.1  christos 
   2006      1.1  christos 0.38,6.RS,11.RA,16.D:D:::Store Byte
   2007      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2008      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2009      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2010      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2011      1.1  christos 	unsigned_word b;
   2012      1.1  christos 	unsigned_word EA;
   2013      1.1  christos 	if (RA_is_0) b = 0;
   2014      1.1  christos 	else         b = *rA;
   2015      1.1  christos 	EA = b + EXTS(D);
   2016      1.1  christos 	STORE(EA, 1, *rS);
   2017      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
   2018      1.1  christos 
   2019      1.1  christos 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
   2020      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2021      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2022      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2023      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2024      1.1  christos 	unsigned_word b;
   2025      1.1  christos 	unsigned_word EA;
   2026      1.1  christos 	if (RA_is_0) b = 0;
   2027      1.1  christos 	else         b = *rA;
   2028      1.1  christos 	EA = b + *rB;
   2029      1.1  christos 	STORE(EA, 1, *rS);
   2030      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
   2031      1.1  christos 
   2032      1.1  christos 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
   2033      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2034      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2035      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2036      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2037      1.1  christos 	unsigned_word EA;
   2038      1.1  christos 	if (RA_is_0)
   2039      1.1  christos 	  program_interrupt(processor, cia,
   2040      1.1  christos 	                    illegal_instruction_program_interrupt);
   2041      1.1  christos 	EA = *rA + EXTS(D);
   2042      1.1  christos 	STORE(EA, 1, *rS);
   2043      1.1  christos 	*rA = EA;
   2044      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
   2045      1.1  christos 
   2046      1.1  christos 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
   2047      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2048      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2049      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2050      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2051      1.1  christos 	unsigned_word EA;
   2052      1.1  christos 	if (RA_is_0)
   2053      1.1  christos 	  program_interrupt(processor, cia,
   2054      1.1  christos 	                    illegal_instruction_program_interrupt);
   2055      1.1  christos 	EA = *rA + *rB;
   2056      1.1  christos 	STORE(EA, 1, *rS);
   2057      1.1  christos 	*rA = EA;
   2058      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
   2059      1.1  christos 
   2060      1.1  christos 0.44,6.RS,11.RA,16.D:D:::Store Half Word
   2061      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2062      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2063      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2064      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2065      1.1  christos 	unsigned_word b;
   2066      1.1  christos 	unsigned_word EA;
   2067      1.1  christos 	if (RA_is_0) b = 0;
   2068      1.1  christos 	else         b = *rA;
   2069      1.1  christos 	EA = b + EXTS(D);
   2070      1.1  christos 	STORE(EA, 2, *rS);
   2071      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
   2072      1.1  christos 
   2073      1.1  christos 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
   2074      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2075      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2076      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2077      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2078      1.1  christos 	unsigned_word b;
   2079      1.1  christos 	unsigned_word EA;
   2080      1.1  christos 	if (RA_is_0) b = 0;
   2081      1.1  christos 	else         b = *rA;
   2082      1.1  christos 	EA = b + *rB;
   2083      1.1  christos 	STORE(EA, 2, *rS);
   2084      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
   2085      1.1  christos 
   2086      1.1  christos 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
   2087      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2088      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2089      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2090      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2091      1.1  christos 	unsigned_word EA;
   2092      1.1  christos 	if (RA_is_0)
   2093      1.1  christos 	  program_interrupt(processor, cia,
   2094      1.1  christos 	                    illegal_instruction_program_interrupt);
   2095      1.1  christos 	EA = *rA + EXTS(D);
   2096      1.1  christos 	STORE(EA, 2, *rS);
   2097      1.1  christos 	*rA = EA;
   2098      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
   2099      1.1  christos 
   2100      1.1  christos 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
   2101      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2102      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2103      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2104      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2105      1.1  christos 	unsigned_word EA;
   2106      1.1  christos 	if (RA_is_0)
   2107      1.1  christos 	  program_interrupt(processor, cia,
   2108      1.1  christos 	                    illegal_instruction_program_interrupt);
   2109      1.1  christos 	EA = *rA + *rB;
   2110      1.1  christos 	STORE(EA, 2, *rS);
   2111      1.1  christos 	*rA = EA;
   2112      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
   2113      1.1  christos 
   2114      1.1  christos 0.36,6.RS,11.RA,16.D:D:::Store Word
   2115      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2116      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2117      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2118      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2119      1.1  christos 	unsigned_word b;
   2120      1.1  christos 	unsigned_word EA;
   2121      1.1  christos 	if (RA_is_0) b = 0;
   2122      1.1  christos 	else         b = *rA;
   2123      1.1  christos 	EA = b + EXTS(D);
   2124      1.1  christos 	STORE(EA, 4, *rS);
   2125      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
   2126      1.1  christos 
   2127      1.1  christos 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
   2128      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2129      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2130      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2131      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2132      1.1  christos 	unsigned_word b;
   2133      1.1  christos 	unsigned_word EA;
   2134      1.1  christos 	if (RA_is_0) b = 0;
   2135      1.1  christos 	else         b = *rA;
   2136      1.1  christos 	EA = b + *rB;
   2137      1.1  christos 	STORE(EA, 4, *rS);
   2138      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
   2139      1.1  christos 
   2140      1.1  christos 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
   2141      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2142      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2143      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2144      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2145      1.1  christos 	unsigned_word EA;
   2146      1.1  christos 	if (RA_is_0)
   2147      1.1  christos 	  program_interrupt(processor, cia,
   2148      1.1  christos 	                    illegal_instruction_program_interrupt);
   2149      1.1  christos 	EA = *rA + EXTS(D);
   2150      1.1  christos 	STORE(EA, 4, *rS);
   2151      1.1  christos 	*rA = EA;
   2152      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
   2153      1.1  christos 
   2154      1.1  christos 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
   2155      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2156      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2157      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2158      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2159      1.1  christos 	unsigned_word EA;
   2160      1.1  christos 	if (RA_is_0)
   2161      1.1  christos 	  program_interrupt(processor, cia,
   2162      1.1  christos 	                    illegal_instruction_program_interrupt);
   2163      1.1  christos 	EA = *rA + *rB;
   2164      1.1  christos 	STORE(EA, 4, *rS);
   2165      1.1  christos 	*rA = EA;
   2166      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
   2167      1.1  christos 
   2168      1.1  christos 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
   2169      1.1  christos #	unsigned_word b;
   2170      1.1  christos #	unsigned_word EA;
   2171      1.1  christos #	if (RA_is_0) b = 0;
   2172      1.1  christos #	else         b = *rA;
   2173      1.1  christos #	EA = b + EXTS(DS_0b00);
   2174      1.1  christos #	STORE(EA, 8, *rS);
   2175      1.1  christos 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
   2176      1.1  christos #	unsigned_word b;
   2177      1.1  christos #	unsigned_word EA;
   2178      1.1  christos #	if (RA_is_0) b = 0;
   2179      1.1  christos #	else         b = *rA;
   2180      1.1  christos #	EA = b + *rB;
   2181      1.1  christos #	STORE(EA, 8, *rS);
   2182      1.1  christos 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
   2183      1.1  christos #	unsigned_word EA;
   2184      1.1  christos #	if (RA_is_0)
   2185      1.1  christos #	  program_interrupt(processor, cia
   2186      1.1  christos #	                    illegal_instruction_program_interrupt);
   2187      1.1  christos #	EA = *rA + EXTS(DS_0b00);
   2188      1.1  christos #	STORE(EA, 8, *rS);
   2189      1.1  christos #	*rA = EA;
   2190      1.1  christos 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
   2191      1.1  christos #	unsigned_word EA;
   2192      1.1  christos #	if (RA_is_0)
   2193      1.1  christos #	  program_interrupt(processor, cia
   2194      1.1  christos #	                    illegal_instruction_program_interrupt);
   2195      1.1  christos #	EA = *rA + *rB;
   2196      1.1  christos #	STORE(EA, 8, *rS);
   2197      1.1  christos #	*rA = EA;
   2198      1.1  christos 
   2199      1.1  christos 
   2200      1.1  christos #
   2201      1.1  christos # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
   2202      1.1  christos #
   2203      1.1  christos 
   2204      1.1  christos 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
   2205      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2206      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2207      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2208      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2209      1.1  christos 	unsigned_word b;
   2210      1.1  christos 	unsigned_word EA;
   2211      1.1  christos 	if (RA_is_0) b = 0;
   2212      1.1  christos 	else         b = *rA;
   2213      1.1  christos 	EA = b + *rB;
   2214      1.1  christos 	*rT = SWAP_2(MEM(unsigned, EA, 2));
   2215      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   2216      1.1  christos 
   2217      1.1  christos 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
   2218      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2219      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2220      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2221      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2222      1.1  christos 	unsigned_word b;
   2223      1.1  christos 	unsigned_word EA;
   2224      1.1  christos 	if (RA_is_0) b = 0;
   2225      1.1  christos 	else         b = *rA;
   2226      1.1  christos 	EA = b + *rB;
   2227      1.1  christos 	*rT = SWAP_4(MEM(unsigned, EA, 4));
   2228      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   2229      1.1  christos 
   2230      1.1  christos 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
   2231      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2232      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2233      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2234      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2235      1.1  christos 	unsigned_word b;
   2236      1.1  christos 	unsigned_word EA;
   2237      1.1  christos 	if (RA_is_0) b = 0;
   2238      1.1  christos 	else         b = *rA;
   2239      1.1  christos 	EA = b + *rB;
   2240      1.1  christos 	STORE(EA, 2, SWAP_2(*rS));
   2241      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
   2242      1.1  christos 
   2243      1.1  christos 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
   2244      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2245      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2246      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   2247      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2248      1.1  christos 	unsigned_word b;
   2249      1.1  christos 	unsigned_word EA;
   2250      1.1  christos 	if (RA_is_0) b = 0;
   2251      1.1  christos 	else         b = *rA;
   2252      1.1  christos 	EA = b + *rB;
   2253      1.1  christos 	STORE(EA, 4, SWAP_4(*rS));
   2254      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
   2255      1.1  christos 
   2256      1.1  christos 
   2257      1.1  christos #
   2258      1.1  christos # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
   2259      1.1  christos #
   2260      1.1  christos 
   2261      1.1  christos 0.46,6.RT,11.RA,16.D:D:::Load Multiple Word
   2262      1.1  christos 	unsigned_word EA;
   2263      1.1  christos 	unsigned_word b;
   2264      1.1  christos 	int r;
   2265      1.1  christos 	if (RA_is_0) b = 0;
   2266      1.1  christos 	else         b = *rA;
   2267      1.1  christos 	EA = b + EXTS(D);
   2268      1.1  christos 	r = RT;
   2269      1.1  christos 	if (RA >= r)
   2270      1.1  christos 	  program_interrupt(processor, cia,
   2271      1.1  christos 	                  illegal_instruction_program_interrupt);
   2272      1.1  christos 	if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT || (EA % 4 != 0))
   2273      1.1  christos 	  alignment_interrupt(processor, cia, EA);
   2274      1.1  christos 	while (r <= 31) {
   2275      1.1  christos 	  GPR(r) = MEM(unsigned, EA, 4);
   2276      1.1  christos 	  r = r + 1;
   2277      1.1  christos 	  EA = EA + 4;
   2278      1.1  christos 	}
   2279      1.1  christos 
   2280      1.1  christos 0.47,6.RS,11.RA,16.D:D:::Store Multiple Word
   2281      1.1  christos 	unsigned_word EA;
   2282      1.1  christos 	unsigned_word b;
   2283      1.1  christos 	int r;
   2284      1.1  christos 	if (RA_is_0) b = 0;
   2285      1.1  christos 	else         b = *rA;
   2286      1.1  christos 	EA = b + EXTS(D);
   2287      1.1  christos 	if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT
   2288      1.1  christos 	    || (EA % 4 != 0))
   2289      1.1  christos 	  alignment_interrupt(processor, cia, EA);
   2290      1.1  christos 	r = RS;
   2291      1.1  christos 	while (r <= 31) {
   2292      1.1  christos 	  STORE(EA, 4, GPR(r));
   2293      1.1  christos 	  r = r + 1;
   2294      1.1  christos 	  EA = EA + 4;
   2295      1.1  christos 	}
   2296      1.1  christos 
   2297      1.1  christos 
   2298      1.1  christos #
   2299      1.1  christos # I.3.3.6 Fixed-Point Move Assist Instructions
   2300      1.1  christos #
   2301      1.1  christos 
   2302      1.1  christos 0.31,6.RT,11.RA,16.NB,21.597,31./:X:::Load String Word Immediate
   2303      1.1  christos 	unsigned_word EA;
   2304      1.1  christos 	int n;
   2305      1.1  christos 	int r;
   2306      1.1  christos 	int i;
   2307      1.1  christos 	int nr;
   2308      1.1  christos 	if (RA_is_0) EA = 0;
   2309      1.1  christos 	else         EA = *rA;
   2310      1.1  christos 	if (NB == 0) n = 32;
   2311      1.1  christos 	else         n = NB;
   2312      1.1  christos 	r = RT - 1;
   2313      1.1  christos 	i = 32;
   2314      1.1  christos 	nr = (n + 3) / 4;
   2315      1.1  christos 	if ((RT + nr >= 32)
   2316      1.1  christos 	    ? (RA >= RT || RA < (RT + nr) % 32)
   2317      1.1  christos 	    : (RA >= RT && RA < RT + nr))
   2318      1.1  christos 	  program_interrupt(processor, cia,
   2319      1.1  christos 	                    illegal_instruction_program_interrupt);
   2320      1.1  christos 	if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
   2321      1.1  christos 	  alignment_interrupt(processor, cia, EA);
   2322      1.1  christos 	while (n > 0) {
   2323      1.1  christos 	  if (i == 32) {
   2324      1.1  christos 	    r = (r + 1) % 32;
   2325      1.1  christos 	    GPR(r) = 0;
   2326      1.1  christos 	  }
   2327      1.1  christos 	  GPR(r) |= INSERTED(MEM(unsigned, EA, 1), i, i+7);
   2328      1.1  christos 	  i = i + 8;
   2329      1.1  christos 	  if (i == 64) i = 32;
   2330      1.1  christos 	  EA = EA + 1;
   2331      1.1  christos 	  n = n - 1;
   2332      1.1  christos 	}
   2333      1.1  christos 
   2334      1.1  christos 0.31,6.RT,11.RA,16.RB,21.533,31./:X:::Load String Word Indexed
   2335      1.1  christos 	unsigned_word EA;
   2336      1.1  christos 	unsigned_word b;
   2337      1.1  christos 	int n;
   2338      1.1  christos 	int r;
   2339      1.1  christos 	int i;
   2340      1.1  christos 	int nr;
   2341      1.1  christos 	if (RA_is_0) b = 0;
   2342      1.1  christos 	else         b = *rA;
   2343      1.1  christos 	EA = b + *rB;
   2344      1.1  christos 	n = EXTRACTED32(XER, 25, 31);
   2345      1.1  christos 	r = RT - 1;
   2346      1.1  christos 	i = 32;
   2347      1.1  christos 	nr = (n + 3) / 4;
   2348      1.1  christos 	if (((RT + nr >= 32)
   2349      1.1  christos 	     ? ((RA >= RT || RA < (RT + nr) % 32)
   2350      1.1  christos 	        || (RB >= RT || RB < (RT + nr) % 32))
   2351      1.1  christos 	     : ((RA >= RT && RA < RT + nr)
   2352      1.1  christos 	        || (RB >= RT && RB < RT + nr)))
   2353      1.1  christos 	    || (RT == RA || RT == RB))
   2354      1.1  christos 	  program_interrupt(processor, cia,
   2355      1.1  christos 	                  illegal_instruction_program_interrupt);
   2356      1.1  christos 	if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
   2357      1.1  christos 	  alignment_interrupt(processor, cia, EA);
   2358      1.1  christos 	while (n > 0) {
   2359      1.1  christos 	  if (i == 32) {
   2360      1.1  christos 	    r = (r + 1) % 32;
   2361      1.1  christos 	    GPR(r) = 0;
   2362      1.1  christos 	  }
   2363      1.1  christos 	  GPR(r) |= INSERTED(MEM(unsigned, EA, 1), i, i+7);
   2364      1.1  christos 	  i = i + 8;
   2365      1.1  christos 	  if (i == 64) i = 32;
   2366      1.1  christos 	  EA = EA + 1;
   2367      1.1  christos 	  n = n - 1;
   2368      1.1  christos 	}
   2369      1.1  christos 
   2370      1.1  christos 0.31,6.RS,11.RA,16.NB,21.725,31./:X:::Store String Word Immedate
   2371      1.1  christos 	unsigned_word EA;
   2372      1.1  christos 	int n;
   2373      1.1  christos 	int r;
   2374      1.1  christos 	int i;
   2375      1.1  christos 	if (RA_is_0) EA = 0;
   2376      1.1  christos 	else         EA = *rA;
   2377      1.1  christos 	if (NB == 0) n = 32;
   2378      1.1  christos 	else         n = NB;
   2379      1.1  christos 	r = RS - 1;
   2380      1.1  christos 	i = 32;
   2381      1.1  christos 	if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
   2382      1.1  christos 	  alignment_interrupt(processor, cia, EA);
   2383      1.1  christos 	while (n > 0) {
   2384      1.1  christos 	  if (i == 32) r = (r + 1) % 32;
   2385      1.1  christos 	  STORE(EA, 1, EXTRACTED(GPR(r), i, i+7));
   2386      1.1  christos 	  i = i + 8;
   2387      1.1  christos 	  if (i == 64) i = 32;
   2388      1.1  christos 	  EA = EA + 1;
   2389      1.1  christos 	  n = n - 1;
   2390      1.1  christos 	}
   2391      1.1  christos 
   2392      1.1  christos 0.31,6.RS,11.RA,16.RB,21.661,31./:X:::Store String Word Indexed
   2393      1.1  christos 	unsigned_word EA;
   2394      1.1  christos 	unsigned_word b;
   2395      1.1  christos 	int n;
   2396      1.1  christos 	int r;
   2397      1.1  christos 	int i;
   2398      1.1  christos 	if (RA_is_0) b = 0;
   2399      1.1  christos 	else         b = *rA;
   2400      1.1  christos 	EA = b + *rB;
   2401      1.1  christos 	if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
   2402      1.1  christos 	  alignment_interrupt(processor, cia, EA);
   2403      1.1  christos 	n = EXTRACTED32(XER, 25, 31);
   2404      1.1  christos 	r = RS - 1;
   2405      1.1  christos 	i = 32;
   2406      1.1  christos 	while (n > 0) {
   2407      1.1  christos 	  if (i == 32) r = (r + 1) % 32;
   2408      1.1  christos 	  STORE(EA, 1, EXTRACTED(GPR(r), i, i+7));
   2409      1.1  christos 	  i = i + 8;
   2410      1.1  christos 	  if (i == 64) i = 32;
   2411      1.1  christos 	  EA = EA + 1;
   2412      1.1  christos 	  n = n - 1;
   2413      1.1  christos 	}
   2414      1.1  christos 
   2415      1.1  christos 
   2416      1.1  christos #
   2417      1.1  christos # I.3.3.7 Storage Synchronization Instructions
   2418      1.1  christos #
   2419      1.1  christos # HACK: Rather than monitor addresses looking for a reason
   2420      1.1  christos #       to cancel a reservation.  This code instead keeps
   2421      1.1  christos #	a copy of the data read from memory.  Before performing
   2422      1.1  christos #	a store, the memory area is checked to see if it has
   2423      1.1  christos #	been changed.
   2424      1.1  christos 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
   2425      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
   2426      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_IU,    1,  2,  0
   2427      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_IU,    1,  2,  0
   2428      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   2429      1.1  christos 	unsigned_word b;
   2430      1.1  christos 	unsigned_word EA;
   2431      1.1  christos 	if (RA_is_0) b = 0;
   2432      1.1  christos 	else         b = *rA;
   2433      1.1  christos 	EA = b + *rB;
   2434      1.1  christos 	RESERVE = 1;
   2435      1.1  christos 	RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
   2436      1.1  christos 	RESERVE_DATA = MEM(unsigned, EA, 4);
   2437      1.1  christos 	*rT = RESERVE_DATA;
   2438      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   2439      1.1  christos 
   2440      1.1  christos 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
   2441      1.1  christos 	unsigned_word b;
   2442      1.1  christos 	unsigned_word EA;
   2443      1.1  christos 	if (RA_is_0) b = 0;
   2444      1.1  christos 	else         b = *rA;
   2445      1.1  christos 	EA = b + *rB;
   2446      1.1  christos 	RESERVE = 1;
   2447      1.1  christos 	RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
   2448      1.1  christos 	RESERVE_DATA = MEM(unsigned, EA, 8);
   2449      1.1  christos 	*rT = RESERVE_DATA;
   2450      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   2451      1.1  christos 
   2452      1.1  christos 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
   2453      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2454      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   8,  8,  0
   2455      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   8,  8,  0
   2456      1.1  christos *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  3,  0
   2457      1.1  christos 	unsigned_word b;
   2458      1.1  christos 	unsigned_word EA;
   2459      1.1  christos 	if (RA_is_0) b = 0;
   2460      1.1  christos 	else         b = *rA;
   2461      1.1  christos 	EA = b + *rB;
   2462      1.1  christos 	if (RESERVE) {
   2463      1.1  christos 	  if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
   2464      1.1  christos 	      && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
   2465      1.1  christos 	    STORE(EA, 4, *rS);
   2466      1.1  christos 	    CR_SET_XER_SO(0, cr_i_zero);
   2467      1.1  christos 	  }
   2468      1.1  christos 	  else {
   2469      1.1  christos 	    /* ment to randomly to store, we never do! */	
   2470      1.1  christos 	    CR_SET_XER_SO(0, 0);
   2471      1.1  christos 	  }
   2472      1.1  christos 	  RESERVE = 0;
   2473      1.1  christos 	}
   2474      1.1  christos 	else {
   2475      1.1  christos 	  CR_SET_XER_SO(0, 0);
   2476      1.1  christos 	}
   2477      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
   2478      1.1  christos 
   2479      1.1  christos 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
   2480      1.1  christos 	unsigned_word b;
   2481      1.1  christos 	unsigned_word EA;
   2482      1.1  christos 	if (RA_is_0) b = 0;
   2483      1.1  christos 	else         b = *rA;
   2484      1.1  christos 	EA = b + *rB;
   2485      1.1  christos 	if (RESERVE) {
   2486      1.1  christos 	  if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
   2487      1.1  christos 	      && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
   2488      1.1  christos 	    STORE(EA, 8, *rS);
   2489      1.1  christos 	    CR_SET_XER_SO(0, cr_i_zero);
   2490      1.1  christos 	  }
   2491      1.1  christos 	  else {
   2492      1.1  christos 	    /* ment to randomly to store, we never do */	
   2493      1.1  christos 	    CR_SET_XER_SO(0, 0);
   2494      1.1  christos 	  }
   2495      1.1  christos 	  RESERVE = 0;
   2496      1.1  christos 	}
   2497      1.1  christos 	else {
   2498      1.1  christos 	  CR_SET_XER_SO(0, 0);
   2499      1.1  christos 	}
   2500      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
   2501      1.1  christos 
   2502      1.1  christos 0.31,6./,9.L,11./,16./,21.598,31./:X::sync:Synchronize
   2503      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2504      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   2505      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   2506      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
   2507      1.1  christos 	/* do nothing */
   2508      1.1  christos 
   2509      1.1  christos 
   2510      1.1  christos #
   2511      1.1  christos # I.3.3.9 Fixed-Point Arithmetic Instructions
   2512      1.1  christos #
   2513      1.1  christos 
   2514      1.1  christos 0.14,6.RT,11.RA,16.SI:D:::Add Immediate
   2515      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2516      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2517      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_SRU,   1,  1,  0
   2518      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2519      1.1  christos 	if (RA_is_0)	*rT = EXTS(SI);
   2520      1.1  christos 	else		*rT = *rA + EXTS(SI);
   2521      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
   2522      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
   2523      1.1  christos 
   2524      1.1  christos 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
   2525      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2526      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2527      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_SRU,   1,  1,  0
   2528      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2529      1.1  christos 	if (RA_is_0)	*rT = EXTS(SI) << 16;
   2530      1.1  christos 	else		*rT = *rA + (EXTS(SI) << 16);
   2531      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
   2532      1.1  christos 	PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
   2533      1.1  christos 
   2534      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
   2535      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2536      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2537      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_SRU,   1,  1,  0
   2538      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2539      1.1  christos 	ALU_BEGIN(*rA);
   2540      1.1  christos 	ALU_ADD(*rB);
   2541      1.1  christos 	ALU_END(*rT, 0/*CA*/, OE, Rc);
   2542      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2543      1.1  christos 
   2544      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
   2545      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2546      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2547      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2548      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2549      1.1  christos 	ALU_BEGIN(*rA);
   2550      1.1  christos 	ALU_NOT;
   2551      1.1  christos 	ALU_ADD(*rB);
   2552      1.1  christos 	ALU_ADD(1);
   2553      1.1  christos 	ALU_END(*rT, 0/*CA*/, OE, Rc);
   2554      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2555      1.1  christos 
   2556      1.1  christos 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
   2557      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2558      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2559      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2560      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2561      1.1  christos 	ALU_BEGIN(*rA);
   2562      1.1  christos 	ALU_ADD(EXTS(SI));
   2563      1.1  christos 	ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
   2564      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
   2565      1.1  christos 
   2566      1.1  christos 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
   2567      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2568      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2569      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2570      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2571      1.1  christos 	ALU_BEGIN(*rA);
   2572      1.1  christos 	ALU_ADD(EXTS(SI));
   2573      1.1  christos 	ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
   2574      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
   2575      1.1  christos 
   2576      1.1  christos 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
   2577      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2578      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2579      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2580      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2581      1.1  christos 	ALU_BEGIN(*rA);
   2582      1.1  christos 	ALU_NOT;
   2583      1.1  christos 	ALU_ADD(EXTS(SI));
   2584      1.1  christos 	ALU_ADD(1);
   2585      1.1  christos 	ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
   2586      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
   2587      1.1  christos 
   2588      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
   2589      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2590      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2591      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2592      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2593      1.1  christos 	ALU_BEGIN(*rA);
   2594      1.1  christos 	ALU_ADD(*rB);
   2595      1.1  christos 	ALU_END(*rT, 1/*CA*/, OE, Rc);
   2596      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2597      1.1  christos 
   2598      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
   2599      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2600      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2601      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2602      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2603      1.1  christos 	/* RT <- ~RA + RB + 1 === RT <- RB - RA */
   2604      1.1  christos 	ALU_BEGIN(*rA);
   2605      1.1  christos 	ALU_NOT;
   2606      1.1  christos 	ALU_ADD(*rB);
   2607      1.1  christos 	ALU_ADD(1);
   2608      1.1  christos 	ALU_END(*rT, 1/*CA*/, OE, Rc);
   2609      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2610      1.1  christos 
   2611      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
   2612      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2613      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2614      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2615      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2616      1.1  christos 	ALU_BEGIN(*rA);
   2617      1.1  christos 	ALU_ADD(*rB);
   2618      1.1  christos 	ALU_ADD_CA;
   2619      1.1  christos 	ALU_END(*rT, 1/*CA*/, OE, Rc);
   2620      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2621      1.1  christos 
   2622      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
   2623      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2624      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2625      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2626      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2627      1.1  christos 	ALU_BEGIN(*rA);
   2628      1.1  christos 	ALU_NOT;
   2629      1.1  christos 	ALU_ADD(*rB);
   2630      1.1  christos 	ALU_ADD_CA;
   2631      1.1  christos 	ALU_END(*rT, 1/*CA*/, OE, Rc);
   2632      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2633      1.1  christos 
   2634      1.1  christos 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
   2635      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2636      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2637      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2638      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2639      1.1  christos 	ALU_BEGIN(*rA);
   2640      1.1  christos 	ALU_ADD_CA;
   2641      1.1  christos 	ALU_ADD(-1);
   2642      1.1  christos 	ALU_END(*rT, 1/*CA*/, OE, Rc);
   2643      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
   2644      1.1  christos 
   2645      1.1  christos 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
   2646      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2647      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2648      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2649      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2650      1.1  christos 	ALU_BEGIN(*rA);
   2651      1.1  christos 	ALU_NOT;
   2652      1.1  christos 	ALU_ADD_CA;
   2653      1.1  christos 	ALU_ADD(-1);
   2654      1.1  christos 	ALU_END(*rT, 1/*CA*/, OE, Rc);
   2655      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
   2656      1.1  christos 
   2657      1.1  christos 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
   2658      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2659      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2660      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2661      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2662      1.1  christos 	ALU_BEGIN(*rA);
   2663      1.1  christos 	ALU_ADD_CA;
   2664      1.1  christos 	ALU_END(*rT, 1/*CA*/, OE, Rc);
   2665      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
   2666      1.1  christos 
   2667      1.1  christos 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
   2668      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2669      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2670      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2671      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2672      1.1  christos 	ALU_BEGIN(*rA);
   2673      1.1  christos 	ALU_NOT;
   2674      1.1  christos 	ALU_ADD_CA;
   2675      1.1  christos 	ALU_END(*rT, 1/*CA*/, OE, Rc);
   2676      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
   2677      1.1  christos 
   2678      1.1  christos 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
   2679      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2680      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2681      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2682      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2683      1.1  christos 	ALU_BEGIN(*rA);
   2684      1.1  christos 	ALU_NOT;
   2685      1.1  christos 	ALU_ADD(1);
   2686      1.1  christos 	ALU_END(*rT,0/*CA*/,OE,Rc);
   2687      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
   2688      1.1  christos 
   2689      1.1  christos 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
   2690      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    5,  5,  0
   2691      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   2692      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   2693      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
   2694      1.1  christos 	signed_word prod = *rA * EXTS(SI);
   2695      1.1  christos 	*rT = prod;
   2696      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
   2697      1.1  christos 
   2698      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
   2699      1.1  christos 
   2700      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
   2701      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    5,  5,  0
   2702      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    5,  5,  0
   2703      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    5,  5,  0
   2704      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  4,  4,  0
   2705      1.1  christos 	int64_t a = (int32_t)(*rA);
   2706      1.1  christos 	int64_t b = (int32_t)(*rB);
   2707      1.1  christos 	int64_t prod = a * b;
   2708      1.1  christos 	signed_word t = prod;
   2709      1.1  christos 	*rT = *rA * *rB;
   2710      1.1  christos 	if (t != prod && OE)
   2711      1.1  christos 	  XER |= (xer_overflow | xer_summary_overflow);
   2712      1.1  christos 	CR0_COMPARE(t, 0, Rc);
   2713      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2714      1.1  christos 
   2715      1.1  christos 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
   2716      1.1  christos 
   2717      1.1  christos 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
   2718      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    5,  5,  0
   2719      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    5,  5,  0
   2720      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    5,  5,  0
   2721      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  4,  4,  0
   2722      1.1  christos 	int64_t a = (int32_t)(*rA);
   2723      1.1  christos 	int64_t b = (int32_t)(*rB);
   2724      1.1  christos 	int64_t prod = a * b;
   2725      1.1  christos 	signed_word t = EXTRACTED64(prod, 0, 31);
   2726      1.1  christos 	*rT = t;
   2727      1.1  christos 	CR0_COMPARE(t, 0, Rc);
   2728      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2729      1.1  christos 
   2730      1.1  christos 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
   2731      1.1  christos 
   2732      1.1  christos 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::mulhwu:Multiply High Word Unsigned
   2733      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    10, 10, 0
   2734      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    6,  6,  0
   2735      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    6,  6,  0
   2736      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  4,  4,  0
   2737      1.1  christos 	uint64_t a = (uint32_t)(*rA);
   2738      1.1  christos 	uint64_t b = (uint32_t)(*rB);
   2739      1.1  christos 	uint64_t prod = a * b;
   2740      1.1  christos 	signed_word t = EXTRACTED64(prod, 0, 31);
   2741      1.1  christos 	*rT = t;
   2742      1.1  christos 	CR0_COMPARE(t, 0, Rc);
   2743      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2744      1.1  christos 
   2745      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
   2746      1.1  christos 
   2747      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
   2748      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    36, 36, 0
   2749      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    37, 37, 0
   2750      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    37, 37, 0
   2751      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  20, 20, 0
   2752      1.1  christos 	int64_t dividend = (int32_t)(*rA);
   2753      1.1  christos 	int64_t divisor = (int32_t)(*rB);
   2754      1.1  christos 	if (divisor == 0 /* nb 0x8000..0 is sign extended */
   2755      1.1  christos 	    || (dividend == 0x80000000 && divisor == -1)) {
   2756      1.1  christos 	  if (OE)
   2757      1.1  christos 	    XER |= (xer_overflow | xer_summary_overflow);
   2758      1.1  christos 	  CR0_COMPARE(0, 0, Rc);
   2759      1.1  christos 	}
   2760      1.1  christos 	else {
   2761      1.1  christos 	  int64_t quotent = dividend / divisor;
   2762      1.1  christos 	  *rT = quotent;
   2763      1.1  christos 	  CR0_COMPARE((signed_word)quotent, 0, Rc);
   2764      1.1  christos 	}
   2765      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2766      1.1  christos 
   2767      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
   2768      1.1  christos 
   2769      1.1  christos 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
   2770      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    36, 36, 0
   2771      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    37, 37, 0
   2772      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    37, 37, 0
   2773      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  20, 20, 0
   2774      1.1  christos 	uint64_t dividend = (uint32_t)(*rA);
   2775      1.1  christos 	uint64_t divisor = (uint32_t)(*rB);
   2776      1.1  christos 	if (divisor == 0) {
   2777      1.1  christos 	  if (OE)
   2778      1.1  christos 	    XER |= (xer_overflow | xer_summary_overflow);
   2779      1.1  christos 	  CR0_COMPARE(0, 0, Rc);
   2780      1.1  christos 	}
   2781      1.1  christos 	else {
   2782      1.1  christos 	  uint64_t quotent = dividend / divisor;
   2783      1.1  christos 	  *rT = quotent;
   2784      1.1  christos 	  CR0_COMPARE((signed_word)quotent, 0, Rc);
   2785      1.1  christos 	}
   2786      1.1  christos 	PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
   2787      1.1  christos 
   2788      1.1  christos 
   2789      1.1  christos #
   2790      1.1  christos # I.3.3.10 Fixed-Point Compare Instructions
   2791      1.1  christos #
   2792      1.1  christos 
   2793      1.1  christos 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
   2794      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2795      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2796      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_SRU,   1,  1,  0
   2797      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2798      1.1  christos 	if (!is_64bit_mode && L)
   2799      1.1  christos 	  program_interrupt(processor, cia,
   2800      1.1  christos 	                    illegal_instruction_program_interrupt);
   2801      1.1  christos 	else {
   2802      1.1  christos 	  signed_word a;
   2803      1.1  christos 	  signed_word b = EXTS(SI);
   2804      1.1  christos 	  if (L == 0)
   2805      1.1  christos 	    a = EXTENDED(*rA);
   2806      1.1  christos 	  else
   2807      1.1  christos 	    a = *rA;
   2808      1.1  christos 	  CR_COMPARE(BF, a, b);
   2809      1.1  christos 	}
   2810      1.1  christos 	PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
   2811      1.1  christos 
   2812      1.1  christos 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
   2813      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2814      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2815      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_SRU,   1,  1,  0
   2816      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2817      1.1  christos 	if (!is_64bit_mode && L)
   2818      1.1  christos 	  program_interrupt(processor, cia,
   2819      1.1  christos 	                    illegal_instruction_program_interrupt);
   2820      1.1  christos 	else {
   2821      1.1  christos 	  signed_word a;
   2822      1.1  christos 	  signed_word b;
   2823      1.1  christos 	  if (L == 0) {
   2824      1.1  christos 	    a = EXTENDED(*rA);
   2825      1.1  christos 	    b = EXTENDED(*rB);
   2826      1.1  christos 	  }
   2827      1.1  christos 	  else {
   2828      1.1  christos 	    a = *rA;
   2829      1.1  christos 	    b = *rB;
   2830      1.1  christos 	  }
   2831      1.1  christos 	  CR_COMPARE(BF, a, b);
   2832      1.1  christos 	}
   2833      1.1  christos 	PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
   2834      1.1  christos 
   2835      1.1  christos 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
   2836      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2837      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2838      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_SRU,   1,  1,  0
   2839      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2840      1.1  christos 	if (!is_64bit_mode && L)
   2841      1.1  christos 	  program_interrupt(processor, cia,
   2842      1.1  christos 	                    illegal_instruction_program_interrupt);
   2843      1.1  christos 	else {
   2844      1.1  christos 	  unsigned_word a;
   2845      1.1  christos 	  unsigned_word b = UI;
   2846      1.1  christos 	  if (L == 0)
   2847      1.1  christos 	    a = MASKED(*rA, 32, 63);
   2848      1.1  christos 	  else
   2849      1.1  christos 	    a = *rA;
   2850      1.1  christos 	  CR_COMPARE(BF, a, b);
   2851      1.1  christos 	}
   2852      1.1  christos 	PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
   2853      1.1  christos 
   2854      1.1  christos 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
   2855      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2856      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2857      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_SRU,   1,  1,  0
   2858      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2859      1.1  christos 	if (!is_64bit_mode && L)
   2860      1.1  christos 	  program_interrupt(processor, cia,
   2861      1.1  christos 	                    illegal_instruction_program_interrupt);
   2862      1.1  christos 	else {
   2863      1.1  christos 	  unsigned_word a;
   2864      1.1  christos 	  unsigned_word b;
   2865      1.1  christos 	  if (L == 0) {
   2866      1.1  christos 	    a = MASKED(*rA, 32, 63);
   2867      1.1  christos 	    b = MASKED(*rB, 32, 63);
   2868      1.1  christos 	  }
   2869      1.1  christos 	  else {
   2870      1.1  christos 	    a = *rA;
   2871      1.1  christos 	    b = *rB;
   2872      1.1  christos 	  }
   2873      1.1  christos 	  CR_COMPARE(BF, a, b);
   2874      1.1  christos 	}
   2875      1.1  christos 	PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
   2876      1.1  christos 
   2877      1.1  christos 
   2878      1.1  christos #
   2879      1.1  christos # I.3.3.11 Fixed-Point Trap Instructions
   2880      1.1  christos #
   2881      1.1  christos 
   2882      1.1  christos 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
   2883      1.1  christos 	if (!is_64bit_mode)
   2884      1.1  christos 	  program_interrupt(processor, cia,
   2885      1.1  christos 	                    illegal_instruction_program_interrupt);
   2886      1.1  christos 	else {
   2887      1.1  christos 	  signed_word a = *rA;
   2888      1.1  christos 	  signed_word b = EXTS(SI);
   2889      1.1  christos 	  if ((a < b && TO{0})
   2890      1.1  christos 	      || (a > b && TO{1})
   2891      1.1  christos 	      || (a == b && TO{2})
   2892      1.1  christos 	      || ((unsigned_word)a < (unsigned_word)b && TO{3})
   2893      1.1  christos 	      || ((unsigned_word)a > (unsigned_word)b && TO{4})
   2894      1.1  christos 	      )
   2895      1.1  christos 	    program_interrupt(processor, cia,
   2896      1.1  christos 	                      trap_program_interrupt);
   2897      1.1  christos 	}
   2898      1.1  christos 
   2899      1.1  christos 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
   2900      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2901      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
   2902      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
   2903      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2904      1.1  christos 	signed_word a = EXTENDED(*rA);
   2905      1.1  christos 	signed_word b = EXTS(SI);
   2906      1.1  christos 	if ((a < b && TO{0})
   2907      1.1  christos 	    || (a > b && TO{1})
   2908      1.1  christos 	    || (a == b && TO{2})
   2909      1.1  christos 	    || ((unsigned_word)a < (unsigned_word)b && TO{3})
   2910      1.1  christos 	    || ((unsigned_word)a > (unsigned_word)b && TO{4})
   2911      1.1  christos 	    )
   2912      1.1  christos 	  program_interrupt(processor, cia,
   2913      1.1  christos 	                    trap_program_interrupt);
   2914      1.1  christos 
   2915      1.1  christos 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
   2916      1.1  christos 	if (!is_64bit_mode)
   2917      1.1  christos 	  program_interrupt(processor, cia,
   2918      1.1  christos 	                    illegal_instruction_program_interrupt);
   2919      1.1  christos 	else {
   2920      1.1  christos 	  signed_word a = *rA;
   2921      1.1  christos 	  signed_word b = *rB;
   2922      1.1  christos 	  if ((a < b && TO{0})
   2923      1.1  christos 	      || (a > b && TO{1})
   2924      1.1  christos 	      || (a == b && TO{2})
   2925      1.1  christos 	      || ((unsigned_word)a < (unsigned_word)b && TO{3})
   2926      1.1  christos 	      || ((unsigned_word)a > (unsigned_word)b && TO{4})
   2927      1.1  christos 	      )
   2928      1.1  christos 	    program_interrupt(processor, cia,
   2929      1.1  christos 	                      trap_program_interrupt);
   2930      1.1  christos 	}
   2931      1.1  christos 
   2932      1.1  christos 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
   2933      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2934      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
   2935      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
   2936      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2937      1.1  christos 	signed_word a = EXTENDED(*rA);
   2938      1.1  christos 	signed_word b = EXTENDED(*rB);
   2939      1.1  christos 	if (TO == 12 && rA == rB) {
   2940      1.1  christos 	  ITRACE(trace_breakpoint, ("breakpoint\n"));
   2941      1.1  christos 	  cpu_halt(processor, cia, was_trap, 0);
   2942      1.1  christos 	}
   2943      1.1  christos 	else if ((a < b && TO{0})
   2944      1.1  christos 	    || (a > b && TO{1})
   2945      1.1  christos 	    || (a == b && TO{2})
   2946      1.1  christos 	    || ((unsigned_word)a < (unsigned_word)b && TO{3})
   2947      1.1  christos 	    || ((unsigned_word)a > (unsigned_word)b && TO{4})
   2948      1.1  christos 	    )
   2949      1.1  christos 	  program_interrupt(processor, cia,
   2950      1.1  christos 	                    trap_program_interrupt);
   2951      1.1  christos 
   2952      1.1  christos #
   2953      1.1  christos # I.3.3.12 Fixed-Point Logical Instructions
   2954      1.1  christos #
   2955      1.1  christos 
   2956      1.1  christos 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
   2957      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2958      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2959      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2960      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2961      1.1  christos 	*rA = *rS & UI;
   2962      1.1  christos 	CR0_COMPARE(*rA, 0, 1/*Rc*/);
   2963      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   2964      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
   2965      1.1  christos 
   2966      1.1  christos 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
   2967      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2968      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2969      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2970      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2971      1.1  christos 	*rA = *rS & (UI << 16);
   2972      1.1  christos 	CR0_COMPARE(*rA, 0, 1/*Rc*/);
   2973      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   2974      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
   2975      1.1  christos 
   2976      1.1  christos 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
   2977      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2978      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2979      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2980      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2981      1.1  christos 	*rA = *rS | UI;
   2982      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   2983      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
   2984      1.1  christos 
   2985      1.1  christos 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
   2986      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2987      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2988      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2989      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2990      1.1  christos 	*rA = *rS | (UI << 16);
   2991      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   2992      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
   2993      1.1  christos 
   2994      1.1  christos 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
   2995      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2996      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2997      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   2998      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   2999      1.1  christos 	*rA = *rS ^ UI;
   3000      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3001      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
   3002      1.1  christos 
   3003      1.1  christos 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
   3004      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3005      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3006      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3007      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3008      1.1  christos 	*rA = *rS ^ (UI << 16);
   3009      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3010      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
   3011      1.1  christos 
   3012      1.1  christos 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
   3013      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3014      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3015      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3016      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3017      1.1  christos 	*rA = *rS & *rB;
   3018      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3019      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3020      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
   3021      1.1  christos 
   3022      1.1  christos 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
   3023      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3024      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3025      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3026      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3027      1.1  christos 	*rA = *rS | *rB;
   3028      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3029      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3030      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
   3031      1.1  christos 
   3032      1.1  christos 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
   3033      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3034      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3035      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3036      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3037      1.1  christos 	*rA = *rS ^ *rB;
   3038      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3039      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3040      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
   3041      1.1  christos 
   3042      1.1  christos 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
   3043      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3044      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3045      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3046      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3047      1.1  christos 	*rA = ~(*rS & *rB);
   3048      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3049      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3050      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
   3051      1.1  christos 
   3052      1.1  christos 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
   3053      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3054      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3055      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3056      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3057      1.1  christos 	*rA = ~(*rS | *rB);
   3058      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3059      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3060      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
   3061      1.1  christos 
   3062      1.1  christos 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
   3063      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3064      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3065      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3066      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3067      1.1  christos 	*rA = ~(*rS ^ *rB); /* A === B */
   3068      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3069      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3070      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
   3071      1.1  christos 
   3072      1.1  christos 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
   3073      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3074      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3075      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3076      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3077      1.1  christos 	*rA = *rS & ~*rB;
   3078      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3079      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3080      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
   3081      1.1  christos 
   3082      1.1  christos 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
   3083      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3084      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3085      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3086      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3087      1.1  christos 	*rA = *rS | ~*rB;
   3088      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3089      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3090      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
   3091      1.1  christos 
   3092      1.1  christos 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
   3093      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3094      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3095      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3096      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3097      1.1  christos 	*rA = (signed_word)(int8_t)*rS;
   3098      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3099      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3100      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
   3101      1.1  christos 
   3102      1.1  christos 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
   3103      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3104      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3105      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3106      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3107      1.1  christos 	*rA = (signed_word)(int16_t)*rS;
   3108      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3109      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3110      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
   3111      1.1  christos 
   3112      1.1  christos 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
   3113      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3114      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3115      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3116      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3117      1.1  christos #	*rA = (signed_word)(int32_t)*rS;
   3118      1.1  christos #	CR0_COMPARE(*rA, 0, Rc);
   3119      1.1  christos 
   3120      1.1  christos 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
   3121      1.1  christos #	int count = 0;
   3122      1.1  christos #	uint64_t mask = BIT64(0);
   3123      1.1  christos #	uint64_t source = *rS;
   3124      1.1  christos #	while (!(source & mask) && mask != 0) {
   3125      1.1  christos #	  mask >>= 1;
   3126      1.1  christos #	  count++;
   3127      1.1  christos #	}
   3128      1.1  christos #	*rA = count;
   3129      1.1  christos #	CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
   3130      1.1  christos 
   3131      1.1  christos 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
   3132      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3133      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3134      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3135      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3136      1.1  christos 	int count = 0;
   3137      1.1  christos 	uint32_t mask = BIT32(0);
   3138      1.1  christos 	uint32_t source = *rS;
   3139      1.1  christos 	while (!(source & mask) && mask != 0) {
   3140      1.1  christos 	  mask >>= 1;
   3141      1.1  christos 	  count++;
   3142      1.1  christos 	}
   3143      1.1  christos 	*rA = count;
   3144      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3145      1.1  christos 	CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
   3146      1.1  christos 
   3147      1.1  christos 
   3148      1.1  christos #
   3149      1.1  christos # I.3.3.13 Fixed-Point Rotate and Shift Instructions
   3150      1.1  christos #
   3151      1.1  christos 
   3152      1.1  christos 0.30,6.RS,11.RA,16.sh_0_4,21.mb,27.0,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Clear Left
   3153      1.1  christos #	long n = (sh_5 << 4) | sh_0_4;
   3154      1.1  christos #	unsigned_word r = ROTL64(*rS, n);
   3155      1.1  christos #	long b = (mb_5 << 4) | mb_0_4;
   3156      1.1  christos #	unsigned_word m = MASK(b, 63);
   3157      1.1  christos #	signed_word result = r & m;
   3158      1.1  christos #	*rA = result;
   3159      1.1  christos #	ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
   3160      1.1  christos #	CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
   3161      1.1  christos 
   3162      1.1  christos 0.30,6.RS,11.RA,16.sh_0_4,21.me,27.1,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Clear Right
   3163      1.1  christos #	long n = (sh_5 << 4) | sh_0_4;
   3164      1.1  christos #	unsigned_word r = ROTL64(*rS, n);
   3165      1.1  christos #	long e = (me_5 << 4) | me_0_4;
   3166      1.1  christos #	unsigned_word m = MASK(0, e);
   3167      1.1  christos #	signed_word result = r & m;
   3168      1.1  christos #	*rA = result;
   3169      1.1  christos #	CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
   3170      1.1  christos 
   3171      1.1  christos 0.30,6.RS,11.RA,16.sh_0_4,21.mb,27.2,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Clear
   3172      1.1  christos #	long n = (sh_5 << 4) | sh_0_4;
   3173      1.1  christos #	unsigned_word r = ROTL64(*rS, n);
   3174      1.1  christos #	long b = (mb_5 << 4) | mb_0_4;
   3175      1.1  christos #	unsigned_word m = MASK(0, (64-n));
   3176      1.1  christos #	signed_word result = r & m;
   3177      1.1  christos #	*rA = result;
   3178      1.1  christos #	CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
   3179      1.1  christos 
   3180      1.1  christos 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
   3181      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3182      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3183      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3184      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3185      1.1  christos 	long n = SH;
   3186      1.1  christos 	uint32_t s = *rS;
   3187      1.1  christos 	uint32_t r = ROTL32(s, n);
   3188      1.1  christos 	uint32_t m = MASK(MB+32, ME+32);
   3189      1.1  christos 	signed_word result = r & m;
   3190      1.1  christos 	*rA = result;
   3191      1.1  christos 	CR0_COMPARE(result, 0, Rc);
   3192      1.1  christos 	ITRACE(trace_alu,
   3193      1.1  christos 	       ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
   3194      1.1  christos 	        n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
   3195      1.1  christos 		(unsigned long)result, (unsigned long)CR));
   3196      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
   3197      1.1  christos 
   3198      1.1  christos 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
   3199      1.1  christos #	long n = MASKED(*rB, 58, 63);
   3200      1.1  christos #	unsigned_word r = ROTL64(*rS, n);
   3201      1.1  christos #	long b = (mb_5 << 4) | mb_0_4;
   3202      1.1  christos #	unsigned_word m = MASK(b, 63);
   3203      1.1  christos #	signed_word result = r & m;
   3204      1.1  christos #	*rA = result;
   3205      1.1  christos #	CR0_COMPARE(result, 0, Rc);
   3206      1.1  christos 
   3207      1.1  christos 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
   3208      1.1  christos #	long n = MASKED(*rB, 58, 63);
   3209      1.1  christos #	unsigned_word r = ROTL64(*rS, n);
   3210      1.1  christos #	long e = (me_5 << 4) | me_0_4;
   3211      1.1  christos #	unsigned_word m = MASK(0, e);
   3212      1.1  christos #	signed_word result = r & m;
   3213      1.1  christos #	*rA = result;
   3214      1.1  christos #	CR0_COMPARE(result, 0, Rc);
   3215      1.1  christos 
   3216      1.1  christos 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
   3217      1.1  christos 	long n = MASKED(*rB, 59, 63);
   3218      1.1  christos 	uint32_t r = ROTL32(*rS, n);
   3219      1.1  christos 	uint32_t m = MASK(MB+32, ME+32);
   3220      1.1  christos 	signed_word result = r & m;
   3221      1.1  christos 	*rA = result;
   3222      1.1  christos 	CR0_COMPARE(result, 0, Rc);
   3223      1.1  christos 
   3224      1.1  christos 0.30,6.RS,11.RA,16.sh_0_4,21.mb,27.3,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Mask Insert
   3225      1.1  christos #	long n = (sh_5 << 4) | sh_0_4;
   3226      1.1  christos #	unsigned_word r = ROTL64(*rS, n);
   3227      1.1  christos #	long b = (mb_5 << 4) | mb_0_4;
   3228      1.1  christos #	unsigned_word m = MASK(b, (64-n));
   3229      1.1  christos #	signed_word result = (r & m) | (*rA & ~m)
   3230      1.1  christos #	*rA = result;
   3231      1.1  christos #	CR0_COMPARE(result, 0, Rc);
   3232      1.1  christos 
   3233      1.1  christos 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
   3234      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3235      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3236      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3237      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3238      1.1  christos 	long n = SH;
   3239      1.1  christos 	uint32_t r = ROTL32(*rS, n);
   3240      1.1  christos 	uint32_t m = MASK(MB+32, ME+32);
   3241      1.1  christos 	signed_word result = (r & m) | (*rA & ~m);
   3242      1.1  christos 	*rA = result;
   3243      1.1  christos 	ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
   3244      1.1  christos 	                   n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
   3245      1.1  christos 			   (unsigned long)result));
   3246      1.1  christos 	CR0_COMPARE(result, 0, Rc);
   3247      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
   3248      1.1  christos 
   3249      1.1  christos 
   3250      1.1  christos 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
   3251      1.1  christos 
   3252      1.1  christos 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
   3253      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3254      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3255      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3256      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3257      1.1  christos 	int n = MASKED(*rB, 58, 63);
   3258      1.1  christos 	uint32_t source = *rS;
   3259      1.1  christos 	signed_word shifted;
   3260      1.1  christos 	if (n < 32)
   3261      1.1  christos 	  shifted = (source << n);
   3262      1.1  christos 	else
   3263      1.1  christos 	  shifted = 0;
   3264      1.1  christos 	*rA = shifted;
   3265      1.1  christos 	CR0_COMPARE(shifted, 0, Rc);
   3266      1.1  christos 	ITRACE(trace_alu,
   3267      1.1  christos 	       ("n=%d, source=0x%lx, shifted=0x%lx\n",
   3268      1.1  christos 	        n, (unsigned long)source, (unsigned long)shifted));
   3269      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
   3270      1.1  christos 
   3271      1.1  christos 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
   3272      1.1  christos 
   3273      1.1  christos 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
   3274      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3275      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3276      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3277      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3278      1.1  christos 	int n = MASKED(*rB, 58, 63);
   3279      1.1  christos 	uint32_t source = *rS;
   3280      1.1  christos 	signed_word shifted;
   3281      1.1  christos 	if (n < 32)
   3282      1.1  christos 	  shifted = (source >> n);
   3283      1.1  christos 	else
   3284      1.1  christos 	  shifted = 0;
   3285      1.1  christos 	*rA = shifted;
   3286      1.1  christos 	CR0_COMPARE(shifted, 0, Rc);
   3287      1.1  christos 	ITRACE(trace_alu, \
   3288      1.1  christos 	       ("n=%d, source=0x%lx, shifted=0x%lx\n",
   3289      1.1  christos 	        n, (unsigned long)source, (unsigned long)shifted));
   3290      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
   3291      1.1  christos 
   3292      1.1  christos 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
   3293      1.1  christos 
   3294      1.1  christos 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
   3295      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3296      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3297      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3298      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3299      1.1  christos 	int n = SH;
   3300      1.1  christos 	signed_word r = ROTL32(*rS, /*64*/32-n);
   3301      1.1  christos 	signed_word m = MASK(n+32, 63);
   3302      1.1  christos 	int S = MASKED(*rS, 32, 32);
   3303      1.1  christos 	signed_word shifted = (r & m) | (S ? ~m : 0);
   3304      1.1  christos 	*rA = shifted;
   3305      1.1  christos 	if (S && ((r & ~m) & MASK(32, 63)) != 0)
   3306      1.1  christos 	  XER |= xer_carry;
   3307      1.1  christos 	else
   3308      1.1  christos 	  XER &= ~xer_carry;
   3309      1.1  christos 	CR0_COMPARE(shifted, 0, Rc);
   3310      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
   3311      1.1  christos 			   (long)*rA, (long)*rA, (long)XER));
   3312      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
   3313      1.1  christos 
   3314      1.1  christos 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
   3315      1.1  christos 
   3316      1.1  christos 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
   3317      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3318      1.1  christos *603: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3319      1.1  christos *603e:PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3320      1.1  christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0
   3321      1.1  christos 	uint64_t mask;
   3322      1.1  christos 	int n = MASKED(*rB, 59, 63);
   3323      1.1  christos 	int32_t source = (int32_t)*rS; /* signed to keep sign bit */
   3324      1.1  christos 	int S = (MASKED(*rS,32,32) != 0);
   3325      1.1  christos 	int64_t r = ((uint64_t) source);
   3326      1.1  christos 	r = ((uint64_t) source) << 32 | (uint32_t) source;
   3327      1.1  christos 	r = ROTL64(r,64-n);
   3328      1.1  christos 	if (MASKED(*rB,58,58) == 0)
   3329      1.1  christos 		mask = (uint64_t) MASK64(n+32,63);
   3330      1.1  christos 	else
   3331      1.1  christos 		mask = (uint64_t) 0;
   3332      1.1  christos 	*rA = (signed_word) ((r & mask) | (((int64_t) -1*S) & ~mask)); /* if 64bit will sign extend */
   3333      1.1  christos 	if (S && (MASKED(r & ~mask,32,63)!=0))
   3334      1.1  christos 	  XER |= xer_carry;
   3335      1.1  christos 	else
   3336      1.1  christos 	  XER &= ~xer_carry;
   3337      1.1  christos 	CR0_COMPARE(*rA, 0, Rc);
   3338      1.1  christos 	ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
   3339      1.1  christos 			   (long)*rA, (long)*rA, (long)XER));
   3340      1.1  christos 	PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
   3341      1.1  christos 
   3342      1.1  christos #
   3343      1.1  christos # I.3.3.14 Move to/from System Register Instructions
   3344      1.1  christos #
   3345      1.1  christos 
   3346      1.1  christos 0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
   3347      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3348      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
   3349      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
   3350      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
   3351      1.1  christos 	int n = (SPR{5:9} << 5) | SPR{0:4};
   3352      1.1  christos 	if (SPR{0} && IS_PROBLEM_STATE(processor))
   3353      1.1  christos 	  program_interrupt(processor, cia,
   3354      1.1  christos 	                    privileged_instruction_program_interrupt);
   3355      1.1  christos 	else if (!spr_is_valid(n)
   3356      1.1  christos 	         || spr_is_readonly(n))
   3357      1.1  christos 	  program_interrupt(processor, cia,
   3358      1.1  christos 	                    illegal_instruction_program_interrupt);
   3359      1.1  christos 	else {
   3360      1.1  christos 	  spreg new_val = (spr_length(n) == 64
   3361      1.1  christos 			   ? *rS
   3362      1.1  christos 			   : MASKED(*rS, 32, 63));
   3363      1.1  christos 	  /* HACK - time base registers need to be updated immediately */
   3364      1.1  christos 	  if (WITH_TIME_BASE) {
   3365      1.1  christos 	    switch (n) {
   3366      1.1  christos 	    case spr_tbu:
   3367      1.1  christos 	      cpu_set_time_base(processor,
   3368      1.1  christos 	                        (MASKED64(cpu_get_time_base(processor), 32, 63)
   3369      1.1  christos 	                         | INSERTED64(new_val, 0, 31)));
   3370      1.1  christos 	      break;
   3371      1.1  christos 	    case spr_tbl:
   3372      1.1  christos 	      cpu_set_time_base(processor,
   3373      1.1  christos 	                        (MASKED64(cpu_get_time_base(processor), 0, 31)
   3374      1.1  christos 	                         | INSERTED64(new_val, 32, 63)));
   3375      1.1  christos 	      break;
   3376      1.1  christos 	    case spr_dec:
   3377      1.1  christos 	      cpu_set_decrementer(processor, new_val);
   3378      1.1  christos 	      break;
   3379      1.1  christos 	    default:
   3380      1.1  christos 	      SPREG(n) = new_val;
   3381      1.1  christos 	      break;
   3382      1.1  christos 	    }
   3383      1.1  christos 	  }
   3384      1.1  christos 	  else {
   3385      1.1  christos 	    SPREG(n) = new_val;
   3386      1.1  christos 	  }
   3387      1.1  christos 	}
   3388      1.1  christos 	PPC_INSN_TO_SPR(RS_BITMASK, n);
   3389      1.1  christos 
   3390      1.1  christos 0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
   3391      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3392      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   3393      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   3394      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
   3395      1.1  christos 	int n = (SPR{5:9} << 5) | SPR{0:4};
   3396      1.1  christos 	if (SPR{0} && IS_PROBLEM_STATE(processor))
   3397      1.1  christos 	  program_interrupt(processor, cia,
   3398      1.1  christos 	                    privileged_instruction_program_interrupt);
   3399      1.1  christos 	else if (!spr_is_valid(n))
   3400      1.1  christos 	  program_interrupt(processor, cia,
   3401      1.1  christos 	                    illegal_instruction_program_interrupt);
   3402      1.1  christos 	else {
   3403      1.1  christos 	  /* HACK - time base registers need to be calculated */
   3404      1.1  christos 	  if (WITH_TIME_BASE) {
   3405      1.1  christos 	    switch (n) {
   3406      1.1  christos 	    case spr_dec:
   3407      1.1  christos 	      *rT = cpu_get_decrementer(processor);
   3408      1.1  christos 	      break;
   3409      1.1  christos 		case spr_tbrl:
   3410      1.1  christos 	  	  if (is_64bit_implementation) *rT = TB;
   3411      1.1  christos 	  	  else                         *rT = EXTRACTED64(TB, 32, 63);
   3412      1.1  christos 		break;
   3413      1.1  christos 		case spr_tbru:
   3414      1.1  christos 	  	  if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
   3415      1.1  christos 		  else                         *rT = EXTRACTED64(TB, 0, 31);
   3416      1.1  christos 		break;
   3417      1.1  christos 	    case spr_tbu:
   3418      1.1  christos 	    case spr_tbl:
   3419      1.1  christos 	      /* NOTE - these SPR's are not readable. Use mftb[ul] */
   3420      1.1  christos 	    default:
   3421      1.1  christos 	      *rT = SPREG(n);
   3422      1.1  christos 	      break;
   3423      1.1  christos 	    }
   3424      1.1  christos 	  }
   3425      1.1  christos 	  else {
   3426      1.1  christos 	    *rT = SPREG(n);
   3427      1.1  christos 	  }
   3428      1.1  christos 	}
   3429      1.1  christos 	PPC_INSN_FROM_SPR(RT_BITMASK, n);
   3430      1.1  christos 
   3431      1.1  christos 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
   3432      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
   3433      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   3434      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   3435      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
   3436      1.1  christos 	if (FXM == 0xff) {
   3437      1.1  christos 	  CR = *rS;
   3438      1.1  christos 	}
   3439      1.1  christos 	else {
   3440      1.1  christos 	  unsigned_word mask = 0;
   3441      1.1  christos 	  unsigned_word f;
   3442      1.1  christos 	  for (f = 0; f < 8; f++) {
   3443      1.1  christos 	    if (FXM & (0x80 >> f))
   3444      1.1  christos 	      mask |= (0xf << 4*(7-f));
   3445      1.1  christos 	  }
   3446      1.1  christos 	  CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
   3447      1.1  christos 	}
   3448      1.1  christos 	PPC_INSN_MTCR(RS_BITMASK, FXM);
   3449      1.1  christos 
   3450      1.1  christos 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
   3451      1.1  christos #	CR_SET(BF, EXTRACTED32(XER, 0, 3));
   3452      1.1  christos #	MBLIT32(XER, 0, 3, 0);
   3453      1.1  christos 
   3454      1.1  christos 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
   3455      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3456      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   3457      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   3458      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
   3459      1.1  christos 	*rT = (uint32_t)CR;
   3460      1.1  christos 	PPC_INSN_MFCR(RT_BITMASK);
   3461      1.1  christos 
   3462      1.1  christos #
   3463      1.1  christos # I.4.6.2 Floating-Point Load Instructions
   3464      1.1  christos #
   3465      1.1  christos 
   3466      1.1  christos 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
   3467      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   3468      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3469      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3470      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3471      1.1  christos 	unsigned_word b;
   3472      1.1  christos 	unsigned_word EA;
   3473      1.1  christos 	if (RA_is_0) b = 0;
   3474      1.1  christos 	else         b = *rA;
   3475      1.1  christos 	EA = b + EXTS(D);
   3476      1.1  christos 	*frT = DOUBLE(MEM(unsigned, EA, 4));
   3477      1.1  christos 	PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
   3478      1.1  christos 
   3479      1.1  christos 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
   3480      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   3481      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3482      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3483      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3484      1.1  christos 	unsigned_word b;
   3485      1.1  christos 	unsigned_word EA;
   3486      1.1  christos 	if (RA_is_0) b = 0;
   3487      1.1  christos 	else         b = *rA;
   3488      1.1  christos 	EA = b + *rB;
   3489      1.1  christos 	*frT = DOUBLE(MEM(unsigned, EA, 4));
   3490      1.1  christos 	PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   3491      1.1  christos 
   3492      1.1  christos 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
   3493      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   3494      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3495      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3496      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3497      1.1  christos 	unsigned_word EA;
   3498      1.1  christos 	if (RA_is_0)
   3499      1.1  christos 	  program_interrupt(processor, cia,
   3500      1.1  christos 	                    illegal_instruction_program_interrupt);
   3501      1.1  christos 	EA = *rA + EXTS(D);
   3502      1.1  christos 	*frT = DOUBLE(MEM(unsigned, EA, 4));
   3503      1.1  christos 	*rA = EA;
   3504      1.1  christos 	PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
   3505      1.1  christos 
   3506      1.1  christos 0.31,6.FRT,11.RA,16.RB,21.567,31./:X:f::Load Floating-Point Single with Update Indexed
   3507      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   3508      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3509      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3510      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3511      1.1  christos 	unsigned_word EA;
   3512      1.1  christos 	if (RA_is_0)
   3513      1.1  christos 	  program_interrupt(processor, cia,
   3514      1.1  christos 	                    illegal_instruction_program_interrupt);
   3515      1.1  christos 	EA = *rA + *rB;
   3516      1.1  christos 	*frT = DOUBLE(MEM(unsigned, EA, 4));
   3517      1.1  christos 	*rA = EA;
   3518      1.1  christos 	PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   3519      1.1  christos 
   3520      1.1  christos 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
   3521      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   3522      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3523      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3524      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3525      1.1  christos 	unsigned_word b;
   3526      1.1  christos 	unsigned_word EA;
   3527      1.1  christos 	if (RA_is_0) b = 0;
   3528      1.1  christos 	else         b = *rA;
   3529      1.1  christos 	EA = b + EXTS(D);
   3530      1.1  christos 	*frT = MEM(unsigned, EA, 8);
   3531      1.1  christos 	PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
   3532      1.1  christos 
   3533      1.1  christos 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
   3534      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   3535      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3536      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3537      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3538      1.1  christos 	unsigned_word b;
   3539      1.1  christos 	unsigned_word EA;
   3540      1.1  christos 	if (RA_is_0) b = 0;
   3541      1.1  christos 	else         b = *rA;
   3542      1.1  christos 	EA = b + *rB;
   3543      1.1  christos 	*frT = MEM(unsigned, EA, 8);
   3544      1.1  christos 	PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   3545      1.1  christos 
   3546      1.1  christos 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
   3547      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   3548      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3549      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3550      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3551      1.1  christos 	unsigned_word EA;
   3552      1.1  christos 	if (RA_is_0)
   3553      1.1  christos 	  program_interrupt(processor, cia,
   3554      1.1  christos 	                    illegal_instruction_program_interrupt);
   3555      1.1  christos 	EA = *rA + EXTS(D);
   3556      1.1  christos 	*frT = MEM(unsigned, EA, 8);
   3557      1.1  christos 	*rA = EA;
   3558      1.1  christos 	PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
   3559      1.1  christos 
   3560      1.1  christos 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
   3561      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
   3562      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3563      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3564      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3565      1.1  christos 	unsigned_word EA;
   3566      1.1  christos 	if (RA_is_0)
   3567      1.1  christos 	  program_interrupt(processor, cia,
   3568      1.1  christos 	                    illegal_instruction_program_interrupt);
   3569      1.1  christos 	EA = *rA + *rB;
   3570      1.1  christos 	*frT = MEM(unsigned, EA, 8);
   3571      1.1  christos 	*rA = EA;
   3572      1.1  christos 	PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   3573      1.1  christos 
   3574      1.1  christos 
   3575      1.1  christos #
   3576      1.1  christos # I.4.6.3 Floating-Point Store Instructions
   3577      1.1  christos #
   3578      1.1  christos 
   3579      1.1  christos 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
   3580      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3581      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3582      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3583      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3584      1.1  christos 	unsigned_word b;
   3585      1.1  christos 	unsigned_word EA;
   3586      1.1  christos 	if (RA_is_0) b = 0;
   3587      1.1  christos 	else         b = *rA;
   3588      1.1  christos 	EA = b + EXTS(D);
   3589      1.1  christos 	STORE(EA, 4, SINGLE(*frS));
   3590      1.1  christos 	PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
   3591      1.1  christos 
   3592      1.1  christos 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
   3593      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3594      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3595      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3596      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3597      1.1  christos 	unsigned_word b;
   3598      1.1  christos 	unsigned_word EA;
   3599      1.1  christos 	if (RA_is_0) b = 0;
   3600      1.1  christos 	else         b = *rA;
   3601      1.1  christos 	EA = b + *rB;
   3602      1.1  christos 	STORE(EA, 4, SINGLE(*frS));
   3603      1.1  christos 	PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
   3604      1.1  christos 
   3605      1.1  christos 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
   3606      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3607      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3608      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3609      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3610      1.1  christos 	unsigned_word EA;
   3611      1.1  christos 	if (RA_is_0)
   3612      1.1  christos 	  program_interrupt(processor, cia,
   3613      1.1  christos 	                    illegal_instruction_program_interrupt);
   3614      1.1  christos 	EA = *rA + EXTS(D);
   3615      1.1  christos 	STORE(EA, 4, SINGLE(*frS));
   3616      1.1  christos 	*rA = EA;
   3617      1.1  christos 	PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
   3618      1.1  christos 
   3619      1.1  christos 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
   3620      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3621      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3622      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3623      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3624      1.1  christos 	unsigned_word EA;
   3625      1.1  christos 	if (RA_is_0)
   3626      1.1  christos 	  program_interrupt(processor, cia,
   3627      1.1  christos 	                    illegal_instruction_program_interrupt);
   3628      1.1  christos 	EA = *rA + *rB;
   3629      1.1  christos 	STORE(EA, 4, SINGLE(*frS));
   3630      1.1  christos 	*rA = EA;
   3631      1.1  christos 	PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
   3632      1.1  christos 
   3633      1.1  christos 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
   3634      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3635      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3636      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3637      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3638      1.1  christos 	unsigned_word b;
   3639      1.1  christos 	unsigned_word EA;
   3640      1.1  christos 	if (RA_is_0) b = 0;
   3641      1.1  christos 	else         b = *rA;
   3642      1.1  christos 	EA = b + EXTS(D);
   3643      1.1  christos 	STORE(EA, 8, *frS);
   3644      1.1  christos 	PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
   3645      1.1  christos 
   3646      1.1  christos 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
   3647      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3648      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3649      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3650      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3651      1.1  christos 	unsigned_word b;
   3652      1.1  christos 	unsigned_word EA;
   3653      1.1  christos 	if (RA_is_0) b = 0;
   3654      1.1  christos 	else         b = *rA;
   3655      1.1  christos 	EA = b + *rB;
   3656      1.1  christos 	STORE(EA, 8, *frS);
   3657      1.1  christos 	PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
   3658      1.1  christos 
   3659      1.1  christos 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point Integer Word Indexed
   3660      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3661      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3662      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3663      1.1  christos 	unsigned_word b;
   3664      1.1  christos 	unsigned_word EA;
   3665      1.1  christos 	if (RA_is_0) b = 0;
   3666      1.1  christos 	else         b = *rA;
   3667      1.1  christos 	EA = b + *rB;
   3668      1.1  christos 	STORE(EA, 4, *frS);
   3669      1.1  christos 	PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
   3670      1.1  christos 
   3671      1.1  christos 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
   3672      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3673      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3674      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3675      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3676      1.1  christos 	unsigned_word EA;
   3677      1.1  christos 	if (RA_is_0)
   3678      1.1  christos 	  program_interrupt(processor, cia,
   3679      1.1  christos 	                    illegal_instruction_program_interrupt);
   3680      1.1  christos 	EA = *rA + EXTS(D);
   3681      1.1  christos 	STORE(EA, 8, *frS);
   3682      1.1  christos 	*rA = EA;
   3683      1.1  christos 	PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
   3684      1.1  christos 
   3685      1.1  christos 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
   3686      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   3687      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3688      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
   3689      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   3690      1.1  christos 	unsigned_word EA;
   3691      1.1  christos 	if (RA_is_0)
   3692      1.1  christos 	  program_interrupt(processor, cia,
   3693      1.1  christos 	                    illegal_instruction_program_interrupt);
   3694      1.1  christos 	EA = *rA + *rB;
   3695      1.1  christos 	STORE(EA, 8, *frS);
   3696      1.1  christos 	*rA = EA;
   3697      1.1  christos 	PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
   3698      1.1  christos 
   3699      1.1  christos 
   3700      1.1  christos #
   3701      1.1  christos # I.4.6.4 Floating-Point Move Instructions
   3702      1.1  christos #
   3703      1.1  christos 
   3704      1.1  christos 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
   3705      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   3706      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3707      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3708      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3709      1.1  christos 	*frT = *frB;
   3710      1.1  christos 	CR1_UPDATE(Rc);
   3711      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
   3712      1.1  christos 
   3713      1.1  christos 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
   3714      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   3715      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3716      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3717      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3718      1.1  christos 	*frT = *frB ^ BIT64(0);
   3719      1.1  christos 	CR1_UPDATE(Rc);
   3720      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
   3721      1.1  christos 
   3722      1.1  christos 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
   3723      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   3724      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3725      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3726      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3727      1.1  christos 	*frT = *frB & ~BIT64(0);
   3728      1.1  christos 	CR1_UPDATE(Rc);
   3729      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
   3730      1.1  christos 
   3731      1.1  christos 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
   3732      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   3733      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3734      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3735      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3736      1.1  christos 	*frT = *frB | BIT64(0);
   3737      1.1  christos 	CR1_UPDATE(Rc);
   3738      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
   3739      1.1  christos 
   3740      1.1  christos 
   3741      1.1  christos #
   3742      1.1  christos # I.4.6.5 Floating-Point Arithmetic Instructions
   3743      1.1  christos #
   3744      1.1  christos 
   3745      1.1  christos 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
   3746      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   3747      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3748      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3749      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3750      1.1  christos 	FPSCR_BEGIN;
   3751      1.1  christos 	if (is_invalid_operation(processor, cia,
   3752      1.1  christos 	                         *frA, *frB,
   3753      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   3754      1.1  christos 	                         0, /*single?*/
   3755      1.1  christos 	                         0) /*negate?*/) {
   3756      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   3757      1.1  christos 	                                frT, *frA, *frB, 0,
   3758      1.1  christos 	                                0, /*instruction_is_frsp*/
   3759      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   3760      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   3761      1.1  christos 	                                0); /*single-precision*/
   3762      1.1  christos 	}
   3763      1.1  christos 	else {
   3764      1.1  christos 	  /*HACK!*/
   3765      1.1  christos 	  double s = *(double*)frA + *(double*)frB;
   3766      1.1  christos 	  *(double*)frT = s;
   3767      1.1  christos 	}
   3768      1.1  christos 	FPSCR_END(Rc);
   3769      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
   3770      1.1  christos 
   3771      1.1  christos 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
   3772      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   3773      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3774      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3775      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3776      1.1  christos 	FPSCR_BEGIN;
   3777      1.1  christos 	if (is_invalid_operation(processor, cia,
   3778      1.1  christos 	                         *frA, *frB,
   3779      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   3780      1.1  christos 	                         1, /*single?*/
   3781      1.1  christos 	                         0) /*negate?*/) {
   3782      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   3783      1.1  christos 	                                frT, *frA, *frB, 0,
   3784      1.1  christos 	                                0, /*instruction_is_frsp*/
   3785      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   3786      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   3787      1.1  christos 	                                1); /*single-precision*/
   3788      1.1  christos 	}
   3789      1.1  christos 	else {
   3790      1.1  christos 	  /*HACK!*/
   3791      1.1  christos 	  float s = *(double*)frA + *(double*)frB;
   3792      1.1  christos 	  *(double*)frT = s;
   3793      1.1  christos 	}
   3794      1.1  christos 	FPSCR_END(Rc);
   3795      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
   3796      1.1  christos 
   3797      1.1  christos 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
   3798      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   3799      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3800      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3801      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3802      1.1  christos 	FPSCR_BEGIN;
   3803      1.1  christos 	if (is_invalid_operation(processor, cia,
   3804      1.1  christos 	                         *frA, *frB,
   3805      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   3806      1.1  christos 	                         0, /*single?*/
   3807      1.1  christos 	                         1) /*negate?*/) {
   3808      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   3809      1.1  christos 	                                frT, *frA, *frB, 0,
   3810      1.1  christos 	                                0, /*instruction_is_frsp*/
   3811      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   3812      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   3813      1.1  christos 	                                0); /*single-precision*/
   3814      1.1  christos 	}
   3815      1.1  christos 	else {
   3816      1.1  christos 	  /*HACK!*/
   3817      1.1  christos 	  double s = *(double*)frA - *(double*)frB;
   3818      1.1  christos 	  *(double*)frT = s;
   3819      1.1  christos 	}
   3820      1.1  christos 	FPSCR_END(Rc);
   3821      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
   3822      1.1  christos 
   3823      1.1  christos 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
   3824      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   3825      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3826      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3827      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3828      1.1  christos 	FPSCR_BEGIN;
   3829      1.1  christos 	if (is_invalid_operation(processor, cia,
   3830      1.1  christos 	                         *frA, *frB,
   3831      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   3832      1.1  christos 	                         1, /*single?*/
   3833      1.1  christos 	                         1) /*negate?*/) {
   3834      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   3835      1.1  christos 	                                frT, *frA, *frB, 0,
   3836      1.1  christos 	                                0, /*instruction_is_frsp*/
   3837      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   3838      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   3839      1.1  christos 	                                1); /*single-precision*/
   3840      1.1  christos 	}
   3841      1.1  christos 	else {
   3842      1.1  christos 	  /*HACK!*/
   3843      1.1  christos 	  float s = *(double*)frA - *(double*)frB;
   3844      1.1  christos 	  *(double*)frT = s;
   3845      1.1  christos 	}
   3846      1.1  christos 	FPSCR_END(Rc);
   3847      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
   3848      1.1  christos 
   3849      1.1  christos 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
   3850      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
   3851      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   3852      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   3853      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3854      1.1  christos 	FPSCR_BEGIN;
   3855      1.1  christos 	if (is_invalid_operation(processor, cia,
   3856      1.1  christos 	                         *frA, *frC,
   3857      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   3858      1.1  christos 	                         0, /*single?*/
   3859      1.1  christos 	                         0) /*negate?*/) {
   3860      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   3861      1.1  christos 	                                frT, *frA, 0, *frC,
   3862      1.1  christos 	                                0, /*instruction_is_frsp*/
   3863      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   3864      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   3865      1.1  christos 	                                0); /*single-precision*/
   3866      1.1  christos 	}
   3867      1.1  christos 	else {
   3868      1.1  christos 	  /*HACK!*/
   3869      1.1  christos 	  double s = *(double*)frA * *(double*)frC;
   3870      1.1  christos 	  *(double*)frT = s;
   3871      1.1  christos 	}
   3872      1.1  christos 	FPSCR_END(Rc);
   3873      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
   3874      1.1  christos 
   3875      1.1  christos 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
   3876      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   3877      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3878      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3879      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3880      1.1  christos 	FPSCR_BEGIN;
   3881      1.1  christos 	if (is_invalid_operation(processor, cia,
   3882      1.1  christos 	                         *frA, *frC,
   3883      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   3884      1.1  christos 	                         1, /*single?*/
   3885      1.1  christos 	                         0) /*negate?*/) {
   3886      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   3887      1.1  christos 	                                frT, *frA, 0, *frC,
   3888      1.1  christos 	                                0, /*instruction_is_frsp*/
   3889      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   3890      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   3891      1.1  christos 	                                1); /*single-precision*/
   3892      1.1  christos 	}
   3893      1.1  christos 	else {
   3894      1.1  christos 	  /*HACK!*/
   3895      1.1  christos 	  float s = *(double*)frA * *(double*)frC;
   3896      1.1  christos 	  *(double*)frT = s;
   3897      1.1  christos 	}
   3898      1.1  christos 	FPSCR_END(Rc);
   3899      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
   3900      1.1  christos 
   3901      1.1  christos 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
   3902      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   31, 31, 0
   3903      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   33, 33, 0
   3904      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   33, 33, 0
   3905      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   32, 32, 0
   3906      1.1  christos 	FPSCR_BEGIN;
   3907      1.1  christos 	if (is_invalid_operation(processor, cia,
   3908      1.1  christos 	                         *frA, *frB,
   3909      1.1  christos 	                         fpscr_vxsnan | fpscr_vxzdz,
   3910      1.1  christos 	                         0, /*single?*/
   3911      1.1  christos 	                         0) /*negate?*/) {
   3912      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   3913      1.1  christos 	                                frT, *frA, *frB, 0,
   3914      1.1  christos 	                                0, /*instruction_is_frsp*/
   3915      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   3916      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   3917      1.1  christos 	                                0); /*single-precision*/
   3918      1.1  christos 	}
   3919      1.1  christos 	else if (is_invalid_zero_divide (processor, cia,
   3920      1.1  christos 	                                 *frA, *frB,
   3921      1.1  christos 	                                 0 /*single?*/)) {
   3922      1.1  christos 	  invalid_zero_divide_operation (processor, cia,
   3923      1.1  christos 	                                 frT, *frA, *frB,
   3924      1.1  christos 	                                 0 /*single?*/);
   3925      1.1  christos 	}
   3926      1.1  christos 	else {
   3927      1.1  christos 	  /*HACK!*/
   3928      1.1  christos 	  double s = *(double*)frA / *(double*)frB;
   3929      1.1  christos 	  *(double*)frT = s;
   3930      1.1  christos 	}
   3931      1.1  christos 	FPSCR_END(Rc);
   3932      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
   3933      1.1  christos 
   3934      1.1  christos 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
   3935      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   17, 17, 0
   3936      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
   3937      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
   3938      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
   3939      1.1  christos 	FPSCR_BEGIN;
   3940      1.1  christos 	if (is_invalid_operation(processor, cia,
   3941      1.1  christos 	                         *frA, *frB,
   3942      1.1  christos 	                         fpscr_vxsnan | fpscr_vxzdz,
   3943      1.1  christos 	                         1, /*single?*/
   3944      1.1  christos 	                         0) /*negate?*/) {
   3945      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   3946      1.1  christos 	                                frT, *frA, *frB, 0,
   3947      1.1  christos 	                                0, /*instruction_is_frsp*/
   3948      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   3949      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   3950      1.1  christos 	                                1); /*single-precision*/
   3951      1.1  christos 	}
   3952      1.1  christos 	else if (is_invalid_zero_divide (processor, cia,
   3953      1.1  christos 	                                 *frA, *frB,
   3954      1.1  christos 	                                 1 /*single?*/)) {
   3955      1.1  christos 	  invalid_zero_divide_operation (processor, cia,
   3956      1.1  christos 	                                 frT, *frA, *frB,
   3957      1.1  christos 	                                 1 /*single?*/);
   3958      1.1  christos 	}
   3959      1.1  christos 	else {
   3960      1.1  christos 	  /*HACK!*/
   3961      1.1  christos 	  float s = *(double*)frA / *(double*)frB;
   3962      1.1  christos 	  *(double*)frT = s;
   3963      1.1  christos 	}
   3964      1.1  christos 	FPSCR_END(Rc);
   3965      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
   3966      1.1  christos 
   3967  1.1.1.2  christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
   3968      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
   3969      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   3970      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   3971      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   3972      1.1  christos 	FPSCR_BEGIN;
   3973      1.1  christos 	double product; /*HACK! - incorrectly losing precision ... */
   3974      1.1  christos 	/* compute the multiply */
   3975      1.1  christos 	if (is_invalid_operation(processor, cia,
   3976      1.1  christos 	                         *frA, *frC,
   3977      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   3978      1.1  christos 	                         0, /*single?*/
   3979      1.1  christos 	                         0) /*negate?*/) {
   3980      1.1  christos 	  union { double d; uint64_t u; } tmp;
   3981      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   3982      1.1  christos 	                                &tmp.u, *frA, 0, *frC,
   3983      1.1  christos 	                                0, /*instruction_is_frsp*/
   3984      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   3985      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   3986      1.1  christos 	                                0); /*single-precision*/
   3987      1.1  christos 	  product = tmp.d;
   3988      1.1  christos 	}
   3989      1.1  christos 	else {
   3990      1.1  christos 	  /*HACK!*/
   3991      1.1  christos 	  product = *(double*)frA * *(double*)frC;
   3992      1.1  christos 	}
   3993      1.1  christos 	/* compute the add */
   3994      1.1  christos 	if (is_invalid_operation(processor, cia,
   3995      1.1  christos 	                         product, *frB,
   3996      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   3997      1.1  christos 	                         0, /*single?*/
   3998      1.1  christos 	                         0) /*negate?*/) {
   3999      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4000      1.1  christos 	                                frT, product, *frB, 0,
   4001      1.1  christos 	                                0, /*instruction_is_frsp*/
   4002      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4003      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4004      1.1  christos 	                                0); /*single-precision*/
   4005      1.1  christos 	}
   4006      1.1  christos 	else {
   4007      1.1  christos 	  /*HACK!*/
   4008      1.1  christos 	  double s = product + *(double*)frB;
   4009      1.1  christos 	  *(double*)frT = s;
   4010      1.1  christos 	}
   4011      1.1  christos 	FPSCR_END(Rc);
   4012      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
   4013      1.1  christos 
   4014  1.1.1.2  christos 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
   4015      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   4016      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4017      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4018      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4019      1.1  christos 	FPSCR_BEGIN;
   4020      1.1  christos 	float product; /*HACK! - incorrectly losing precision ... */
   4021      1.1  christos 	/* compute the multiply */
   4022      1.1  christos 	if (is_invalid_operation(processor, cia,
   4023      1.1  christos 	                         *frA, *frC,
   4024      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   4025      1.1  christos 	                         1, /*single?*/
   4026      1.1  christos 	                         0) /*negate?*/) {
   4027      1.1  christos 	  union { double d; uint64_t u; } tmp;
   4028      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4029      1.1  christos 	                                &tmp.u, *frA, 0, *frC,
   4030      1.1  christos 	                                0, /*instruction_is_frsp*/
   4031      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4032      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4033      1.1  christos 	                                0); /*single-precision*/
   4034      1.1  christos 	  product = tmp.d;
   4035      1.1  christos 	}
   4036      1.1  christos 	else {
   4037      1.1  christos 	  /*HACK!*/
   4038      1.1  christos 	  product = *(double*)frA * *(double*)frC;
   4039      1.1  christos 	}
   4040      1.1  christos 	/* compute the add */
   4041      1.1  christos 	if (is_invalid_operation(processor, cia,
   4042      1.1  christos 	                         product, *frB,
   4043      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   4044      1.1  christos 	                         1, /*single?*/
   4045      1.1  christos 	                         0) /*negate?*/) {
   4046      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4047      1.1  christos 	                                frT, product, *frB, 0,
   4048      1.1  christos 	                                0, /*instruction_is_frsp*/
   4049      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4050      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4051      1.1  christos 	                                0); /*single-precision*/
   4052      1.1  christos 	}
   4053      1.1  christos 	else {
   4054      1.1  christos 	  /*HACK!*/
   4055      1.1  christos 	  float s = product + *(double*)frB;
   4056      1.1  christos 	  *(double*)frT = (double)s;
   4057      1.1  christos 	}
   4058      1.1  christos 	FPSCR_END(Rc);
   4059      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
   4060      1.1  christos 
   4061  1.1.1.2  christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
   4062      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
   4063      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   4064      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   4065      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4066      1.1  christos 	FPSCR_BEGIN;
   4067      1.1  christos 	double product; /*HACK! - incorrectly losing precision ... */
   4068      1.1  christos 	/* compute the multiply */
   4069      1.1  christos 	if (is_invalid_operation(processor, cia,
   4070      1.1  christos 	                         *frA, *frC,
   4071      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   4072      1.1  christos 	                         0, /*single?*/
   4073      1.1  christos 	                         0) /*negate?*/) {
   4074      1.1  christos 	  union { double d; uint64_t u; } tmp;
   4075      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4076      1.1  christos 	                                &tmp.u, *frA, 0, *frC,
   4077      1.1  christos 	                                0, /*instruction_is_frsp*/
   4078      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4079      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4080      1.1  christos 	                                0); /*single-precision*/
   4081      1.1  christos 	  product = tmp.d;
   4082      1.1  christos 	}
   4083      1.1  christos 	else {
   4084      1.1  christos 	  /*HACK!*/
   4085      1.1  christos 	  product = *(double*)frA * *(double*)frC;
   4086      1.1  christos 	}
   4087      1.1  christos 	/* compute the subtract */
   4088      1.1  christos 	if (is_invalid_operation(processor, cia,
   4089      1.1  christos 	                         product, *frB,
   4090      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   4091      1.1  christos 	                         0, /*single?*/
   4092      1.1  christos 	                         0) /*negate?*/) {
   4093      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4094      1.1  christos 	                                frT, product, *frB, 0,
   4095      1.1  christos 	                                0, /*instruction_is_frsp*/
   4096      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4097      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4098      1.1  christos 	                                0); /*single-precision*/
   4099      1.1  christos 	}
   4100      1.1  christos 	else {
   4101      1.1  christos 	  /*HACK!*/
   4102      1.1  christos 	  double s = product - *(double*)frB;
   4103      1.1  christos 	  *(double*)frT = s;
   4104      1.1  christos 	}
   4105      1.1  christos 	FPSCR_END(Rc);
   4106      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
   4107      1.1  christos 
   4108  1.1.1.2  christos 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
   4109      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   4110      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4111      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4112      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4113      1.1  christos 	FPSCR_BEGIN;
   4114      1.1  christos 	float product; /*HACK! - incorrectly losing precision ... */
   4115      1.1  christos 	/* compute the multiply */
   4116      1.1  christos 	if (is_invalid_operation(processor, cia,
   4117      1.1  christos 	                         *frA, *frC,
   4118      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   4119      1.1  christos 	                         1, /*single?*/
   4120      1.1  christos 	                         0) /*negate?*/) {
   4121      1.1  christos 	  union { double d; uint64_t u; } tmp;
   4122      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4123      1.1  christos 	                                &tmp.u, *frA, 0, *frC,
   4124      1.1  christos 	                                0, /*instruction_is_frsp*/
   4125      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4126      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4127      1.1  christos 	                                0); /*single-precision*/
   4128      1.1  christos 	  product = tmp.d;
   4129      1.1  christos 	}
   4130      1.1  christos 	else {
   4131      1.1  christos 	  /*HACK!*/
   4132      1.1  christos 	  product = *(double*)frA * *(double*)frC;
   4133      1.1  christos 	}
   4134      1.1  christos 	/* compute the subtract */
   4135      1.1  christos 	if (is_invalid_operation(processor, cia,
   4136      1.1  christos 	                         product, *frB,
   4137      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   4138      1.1  christos 	                         1, /*single?*/
   4139      1.1  christos 	                         0) /*negate?*/) {
   4140      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4141      1.1  christos 	                                frT, product, *frB, 0,
   4142      1.1  christos 	                                0, /*instruction_is_frsp*/
   4143      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4144      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4145      1.1  christos 	                                0); /*single-precision*/
   4146      1.1  christos 	}
   4147      1.1  christos 	else {
   4148      1.1  christos 	  /*HACK!*/
   4149      1.1  christos 	  float s = product - *(double*)frB;
   4150      1.1  christos 	  *(double*)frT = (double)s;
   4151      1.1  christos 	}
   4152      1.1  christos 	FPSCR_END(Rc);
   4153      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
   4154      1.1  christos 
   4155  1.1.1.2  christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
   4156      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
   4157      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   4158      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   4159      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4160      1.1  christos 	FPSCR_BEGIN;
   4161      1.1  christos 	double product; /*HACK! - incorrectly losing precision ... */
   4162      1.1  christos 	/* compute the multiply */
   4163      1.1  christos 	if (is_invalid_operation(processor, cia,
   4164      1.1  christos 	                         *frA, *frC,
   4165      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   4166      1.1  christos 	                         0, /*single?*/
   4167      1.1  christos 	                         0) /*negate?*/) {
   4168      1.1  christos 	  union { double d; uint64_t u; } tmp;
   4169      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4170      1.1  christos 	                                &tmp.u, *frA, 0, *frC,
   4171      1.1  christos 	                                0, /*instruction_is_frsp*/
   4172      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4173      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4174      1.1  christos 	                                0); /*single-precision*/
   4175      1.1  christos 	  product = tmp.d;
   4176      1.1  christos 	}
   4177      1.1  christos 	else {
   4178      1.1  christos 	  /*HACK!*/
   4179      1.1  christos 	  product = *(double*)frA * *(double*)frC;
   4180      1.1  christos 	}
   4181      1.1  christos 	/* compute the add */
   4182      1.1  christos 	if (is_invalid_operation(processor, cia,
   4183      1.1  christos 	                         product, *frB,
   4184      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   4185      1.1  christos 	                         0, /*single?*/
   4186      1.1  christos 	                         0) /*negate?*/) {
   4187      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4188      1.1  christos 	                                frT, product, *frB, 0,
   4189      1.1  christos 	                                0, /*instruction_is_frsp*/
   4190      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4191      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4192      1.1  christos 	                                0); /*single-precision*/
   4193      1.1  christos 	}
   4194      1.1  christos 	else {
   4195      1.1  christos 	  /*HACK!*/
   4196      1.1  christos 	  double s = -(product + *(double*)frB);
   4197      1.1  christos 	  *(double*)frT = s;
   4198      1.1  christos 	}
   4199      1.1  christos 	FPSCR_END(Rc);
   4200      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
   4201      1.1  christos 
   4202  1.1.1.2  christos 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
   4203      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   4204      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4205      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4206      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4207      1.1  christos 	FPSCR_BEGIN;
   4208      1.1  christos 	float product; /*HACK! - incorrectly losing precision ... */
   4209      1.1  christos 	/* compute the multiply */
   4210      1.1  christos 	if (is_invalid_operation(processor, cia,
   4211      1.1  christos 	                         *frA, *frC,
   4212      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   4213      1.1  christos 	                         1, /*single?*/
   4214      1.1  christos 	                         0) /*negate?*/) {
   4215      1.1  christos 	  union { double d; uint64_t u; } tmp;
   4216      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4217      1.1  christos 	                                &tmp.u, *frA, 0, *frC,
   4218      1.1  christos 	                                0, /*instruction_is_frsp*/
   4219      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4220      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4221      1.1  christos 	                                0); /*single-precision*/
   4222      1.1  christos 	  product = tmp.d;
   4223      1.1  christos 	}
   4224      1.1  christos 	else {
   4225      1.1  christos 	  /*HACK!*/
   4226      1.1  christos 	  product = *(double*)frA * *(double*)frC;
   4227      1.1  christos 	}
   4228      1.1  christos 	/* compute the add */
   4229      1.1  christos 	if (is_invalid_operation(processor, cia,
   4230      1.1  christos 	                         product, *frB,
   4231      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   4232      1.1  christos 	                         1, /*single?*/
   4233      1.1  christos 	                         0) /*negate?*/) {
   4234      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4235      1.1  christos 	                                frT, product, *frB, 0,
   4236      1.1  christos 	                                0, /*instruction_is_frsp*/
   4237      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4238      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4239      1.1  christos 	                                0); /*single-precision*/
   4240      1.1  christos 	}
   4241      1.1  christos 	else {
   4242      1.1  christos 	  /*HACK!*/
   4243      1.1  christos 	  float s = -(product + *(double*)frB);
   4244      1.1  christos 	  *(double*)frT = (double)s;
   4245      1.1  christos 	}
   4246      1.1  christos 	FPSCR_END(Rc);
   4247      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
   4248      1.1  christos 
   4249  1.1.1.2  christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
   4250      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
   4251      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   4252      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
   4253      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4254      1.1  christos 	FPSCR_BEGIN;
   4255      1.1  christos 	double product; /*HACK! - incorrectly losing precision ... */
   4256      1.1  christos 	/* compute the multiply */
   4257      1.1  christos 	if (is_invalid_operation(processor, cia,
   4258      1.1  christos 	                         *frA, *frC,
   4259      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   4260      1.1  christos 	                         0, /*single?*/
   4261      1.1  christos 	                         0) /*negate?*/) {
   4262      1.1  christos 	  union { double d; uint64_t u; } tmp;
   4263      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4264      1.1  christos 	                                &tmp.u, *frA, 0, *frC,
   4265      1.1  christos 	                                0, /*instruction_is_frsp*/
   4266      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4267      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4268      1.1  christos 	                                0); /*single-precision*/
   4269      1.1  christos 	  product = tmp.d;
   4270      1.1  christos 	}
   4271      1.1  christos 	else {
   4272      1.1  christos 	  /*HACK!*/
   4273      1.1  christos 	  product = *(double*)frA * *(double*)frC;
   4274      1.1  christos 	}
   4275      1.1  christos 	/* compute the subtract */
   4276      1.1  christos 	if (is_invalid_operation(processor, cia,
   4277      1.1  christos 	                         product, *frB,
   4278      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   4279      1.1  christos 	                         0, /*single?*/
   4280      1.1  christos 	                         0) /*negate?*/) {
   4281      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4282      1.1  christos 	                                frT, product, *frB, 0,
   4283      1.1  christos 	                                0, /*instruction_is_frsp*/
   4284      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4285      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4286      1.1  christos 	                                0); /*single-precision*/
   4287      1.1  christos 	}
   4288      1.1  christos 	else {
   4289      1.1  christos 	  /*HACK!*/
   4290      1.1  christos 	  double s = -(product - *(double*)frB);
   4291      1.1  christos 	  *(double*)frT = s;
   4292      1.1  christos 	}
   4293      1.1  christos 	FPSCR_END(Rc);
   4294      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
   4295      1.1  christos 
   4296  1.1.1.2  christos 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
   4297      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   4298      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4299      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4300      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4301      1.1  christos 	FPSCR_BEGIN;
   4302      1.1  christos 	float product; /*HACK! - incorrectly losing precision ... */
   4303      1.1  christos 	/* compute the multiply */
   4304      1.1  christos 	if (is_invalid_operation(processor, cia,
   4305      1.1  christos 	                         *frA, *frC,
   4306      1.1  christos 	                         fpscr_vxsnan | fpscr_vximz,
   4307      1.1  christos 	                         1, /*single?*/
   4308      1.1  christos 	                         0) /*negate?*/) {
   4309      1.1  christos 	  union { double d; uint64_t u; } tmp;
   4310      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4311      1.1  christos 	                                &tmp.u, *frA, 0, *frC,
   4312      1.1  christos 	                                0, /*instruction_is_frsp*/
   4313      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4314      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4315      1.1  christos 	                                0); /*single-precision*/
   4316      1.1  christos 	  product = tmp.d;
   4317      1.1  christos 	}
   4318      1.1  christos 	else {
   4319      1.1  christos 	  /*HACK!*/
   4320      1.1  christos 	  product = *(double*)frA * *(double*)frC;
   4321      1.1  christos 	}
   4322      1.1  christos 	/* compute the subtract */
   4323      1.1  christos 	if (is_invalid_operation(processor, cia,
   4324      1.1  christos 	                         product, *frB,
   4325      1.1  christos 	                         fpscr_vxsnan | fpscr_vxisi,
   4326      1.1  christos 	                         1, /*single?*/
   4327      1.1  christos 	                         0) /*negate?*/) {
   4328      1.1  christos 	  invalid_arithemetic_operation(processor, cia,
   4329      1.1  christos 	                                frT, product, *frB, 0,
   4330      1.1  christos 	                                0, /*instruction_is_frsp*/
   4331      1.1  christos 	                                0, /*instruction_is_convert_to_64bit*/
   4332      1.1  christos 	                                0, /*instruction_is_convert_to_32bit*/
   4333      1.1  christos 	                                0); /*single-precision*/
   4334      1.1  christos 	}
   4335      1.1  christos 	else {
   4336      1.1  christos 	  /*HACK!*/
   4337      1.1  christos 	  float s = -(product - *(double*)frB);
   4338      1.1  christos 	  *(double*)frT = (double)s;
   4339      1.1  christos 	}
   4340      1.1  christos 	FPSCR_END(Rc);
   4341      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
   4342      1.1  christos 
   4343      1.1  christos 
   4344      1.1  christos #
   4345      1.1  christos # I.4.6.6 Floating-Point Rounding and Conversion Instructions
   4346      1.1  christos #
   4347      1.1  christos 
   4348      1.1  christos 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
   4349      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   4350      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4351      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4352      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4353      1.1  christos 	int sign;
   4354      1.1  christos 	int exp;
   4355      1.1  christos 	uint64_t frac_grx;
   4356      1.1  christos 	/***/
   4357      1.1  christos 	  /* split off cases for what to do */
   4358      1.1  christos 	  if (EXTRACTED64(*frB, 1, 11) < 897
   4359      1.1  christos 	      && EXTRACTED64(*frB, 1, 63) > 0) {
   4360      1.1  christos 	      if ((FPSCR & fpscr_ue) == 0) GOTO(Disabled_Exponent_Underflow);
   4361      1.1  christos 	      if ((FPSCR & fpscr_ue) != 0) GOTO(Enabled_Exponent_Underflow);
   4362      1.1  christos 	  }
   4363      1.1  christos 	  if (EXTRACTED64(*frB, 1, 11) > 1150
   4364      1.1  christos 	      && EXTRACTED64(*frB, 1, 11) < 2047) {
   4365      1.1  christos 	      if ((FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
   4366      1.1  christos 	      if ((FPSCR & fpscr_oe) != 0) GOTO(Enabled_Exponent_Overflow);
   4367      1.1  christos 	  }
   4368      1.1  christos 	  if (EXTRACTED64(*frB, 1, 11) > 896
   4369      1.1  christos 	      && EXTRACTED64(*frB, 1, 11) < 1151) GOTO(Normal_Operand);
   4370      1.1  christos 	  if (EXTRACTED64(*frB, 1, 63) == 0) GOTO(Zero_Operand);
   4371      1.1  christos 	  if (EXTRACTED64(*frB, 1, 11) == 2047) {
   4372      1.1  christos 	    if (EXTRACTED64(*frB, 12, 63) == 0) GOTO(Infinity_Operand);
   4373      1.1  christos 	    if (EXTRACTED64(*frB, 12, 12) == 1) GOTO(QNaN_Operand);
   4374      1.1  christos 	    if (EXTRACTED64(*frB, 12, 12) == 0
   4375      1.1  christos 	        && EXTRACTED64(*frB, 13, 63) > 0) GOTO(SNaN_Operand);
   4376      1.1  christos 	  }
   4377      1.1  christos 	/**/
   4378      1.1  christos 	LABEL(Disabled_Exponent_Underflow):
   4379      1.1  christos 	  sign = EXTRACTED64(*frB, 0, 0);
   4380      1.1  christos 	  if (EXTRACTED64(*frB, 1, 11) == 0) {
   4381      1.1  christos 	    exp = -1022;
   4382      1.1  christos 	    frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
   4383      1.1  christos 	  }
   4384      1.1  christos 	  if (EXTRACTED64(*frB, 1, 11) > 0) {
   4385      1.1  christos 	    exp = EXTRACTED64(*frB, 1, 11) - 1023;
   4386      1.1  christos 	    frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
   4387      1.1  christos 	  }
   4388      1.1  christos 	    /* G|R|X == zero from above */
   4389      1.1  christos 	    while (exp < -126) {
   4390      1.1  christos 	      exp = exp + 1;
   4391      1.1  christos 	      frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
   4392      1.1  christos 	                  | MASKED64(frac_grx, 55, 55));
   4393      1.1  christos 	    }
   4394      1.1  christos 	  FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
   4395      1.1  christos 	  Round_Single(processor, sign, &exp, &frac_grx);
   4396      1.1  christos 	  FPSCR_SET_XX(FPSCR & fpscr_fi);
   4397      1.1  christos 	  if (EXTRACTED64(frac_grx, 0, 52) == 0) {
   4398      1.1  christos 	    *frT = INSERTED64(sign, 0, 0);
   4399      1.1  christos 	    if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
   4400      1.1  christos 	    if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
   4401      1.1  christos 	  }
   4402      1.1  christos 	  if (EXTRACTED64(frac_grx, 0, 52) > 0) {
   4403      1.1  christos 	    if (EXTRACTED64(frac_grx, 0, 0) == 1) {
   4404      1.1  christos 	      if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
   4405      1.1  christos 	      if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
   4406      1.1  christos 	    }
   4407      1.1  christos 	    if (EXTRACTED64(frac_grx, 0, 0) == 0) {
   4408      1.1  christos 	      if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
   4409      1.1  christos 	      if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
   4410      1.1  christos 	    }
   4411      1.1  christos 	    /*Normalize_Operand:*/
   4412      1.1  christos 	      while (EXTRACTED64(frac_grx, 0, 0) == 0) {
   4413      1.1  christos 	        exp = exp - 1;
   4414      1.1  christos 	        frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1,  52), 0, 51);
   4415      1.1  christos 	      }
   4416      1.1  christos 	    *frT = (INSERTED64(sign, 0, 0)
   4417      1.1  christos 	            | INSERTED64(exp + 1023, 1, 11)
   4418      1.1  christos 	            | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
   4419      1.1  christos 	  }
   4420      1.1  christos 	  GOTO(Done);
   4421      1.1  christos 	/**/
   4422      1.1  christos 	LABEL(Enabled_Exponent_Underflow):
   4423      1.1  christos 	  FPSCR_SET_UX(1);
   4424      1.1  christos 	  sign = EXTRACTED64(*frB, 0, 0);
   4425      1.1  christos 	  if (EXTRACTED64(*frB, 1, 11) == 0) {
   4426      1.1  christos 	    exp = -1022;
   4427      1.1  christos 	    frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
   4428      1.1  christos 	  }
   4429      1.1  christos 	  if (EXTRACTED64(*frB, 1, 11) > 0) {
   4430      1.1  christos 	    exp = EXTRACTED64(*frB, 1, 11) - 1023;
   4431      1.1  christos 	    frac_grx = (BIT64(0) |
   4432      1.1  christos 	                INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
   4433      1.1  christos 	  }
   4434      1.1  christos 	  /*Normalize_Operand:*/
   4435      1.1  christos 	    while (EXTRACTED64(frac_grx, 0, 0) == 0) {
   4436      1.1  christos 	      exp = exp - 1;
   4437      1.1  christos 	      frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
   4438      1.1  christos 	    }
   4439      1.1  christos 	  Round_Single(processor, sign, &exp, &frac_grx);
   4440      1.1  christos 	  FPSCR_SET_XX(FPSCR & fpscr_fi);
   4441      1.1  christos 	  exp = exp + 192;
   4442      1.1  christos 	  *frT = (INSERTED64(sign, 0, 0)
   4443      1.1  christos 	          | INSERTED64(exp + 1023, 1, 11)
   4444      1.1  christos 	          | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
   4445      1.1  christos 	  if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
   4446      1.1  christos 	  if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
   4447      1.1  christos 	  GOTO(Done);
   4448      1.1  christos 	/**/
   4449      1.1  christos 	LABEL(Disabled_Exponent_Overflow):
   4450      1.1  christos 	  FPSCR_SET_OX(1);
   4451      1.1  christos 	  if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
   4452      1.1  christos 	    if (EXTRACTED64(*frB, 0, 0) == 0) {
   4453      1.1  christos 	      *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
   4454      1.1  christos 	      FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
   4455      1.1  christos 	    }
   4456      1.1  christos 	    if (EXTRACTED64(*frB, 0, 0) == 1) {
   4457      1.1  christos 	      *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
   4458      1.1  christos 	      FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
   4459      1.1  christos 	    }
   4460      1.1  christos 	  }
   4461      1.1  christos 	  if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
   4462      1.1  christos 	    if (EXTRACTED64(*frB, 0, 0) == 0) {
   4463      1.1  christos 	      *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
   4464      1.1  christos 	      FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
   4465      1.1  christos 	    }
   4466      1.1  christos 	    if (EXTRACTED64(*frB, 0, 0) == 1) {
   4467      1.1  christos 	      *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
   4468      1.1  christos 	      FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
   4469      1.1  christos 	    }
   4470      1.1  christos 	  }
   4471      1.1  christos 	  if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
   4472      1.1  christos 	    if (EXTRACTED64(*frB, 0, 0) == 0) {
   4473      1.1  christos 	      *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
   4474      1.1  christos 	      FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
   4475      1.1  christos 	    }
   4476      1.1  christos 	    if (EXTRACTED64(*frB, 0, 0) == 1) {
   4477      1.1  christos 	      *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
   4478      1.1  christos 	      FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
   4479      1.1  christos 	    }
   4480      1.1  christos 	  }
   4481      1.1  christos 	  if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
   4482      1.1  christos 	    if (EXTRACTED64(*frB, 0, 0) == 0) {
   4483      1.1  christos 	      *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
   4484      1.1  christos 	      FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
   4485      1.1  christos 	    }
   4486      1.1  christos 	    if (EXTRACTED64(*frB, 0, 0) == 1) {
   4487      1.1  christos 	      *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
   4488      1.1  christos 	      FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
   4489      1.1  christos 	    }
   4490      1.1  christos 	  }
   4491      1.1  christos 	  /* FPSCR[FR] <- undefined */
   4492      1.1  christos 	  FPSCR_SET_FI(1);
   4493      1.1  christos 	  FPSCR_SET_XX(1);
   4494      1.1  christos 	  GOTO(Done);
   4495      1.1  christos 	/**/
   4496      1.1  christos 	LABEL(Enabled_Exponent_Overflow):
   4497      1.1  christos 	  sign = EXTRACTED64(*frB, 0, 0);
   4498      1.1  christos 	  exp = EXTRACTED64(*frB, 1, 11) - 1023;
   4499      1.1  christos 	  frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
   4500      1.1  christos 	  Round_Single(processor, sign, &exp, &frac_grx);
   4501      1.1  christos 	  FPSCR_SET_XX(FPSCR & fpscr_fi);
   4502      1.1  christos 	/**/
   4503      1.1  christos 	LABEL(Enabled_Overflow):
   4504      1.1  christos 	  FPSCR_SET_OX(1);
   4505      1.1  christos 	  exp = exp - 192;
   4506      1.1  christos 	  *frT = (INSERTED64(sign, 0, 0)
   4507      1.1  christos 	          | INSERTED64(exp + 1023, 1, 11)
   4508      1.1  christos 	          | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
   4509      1.1  christos 	  if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
   4510      1.1  christos 	  if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
   4511      1.1  christos 	  GOTO(Done);
   4512      1.1  christos 	/**/
   4513      1.1  christos 	LABEL(Zero_Operand):
   4514      1.1  christos 	  *frT = *frB;
   4515      1.1  christos 	  if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
   4516      1.1  christos 	  if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
   4517      1.1  christos 	  FPSCR_SET_FR(0);
   4518      1.1  christos 	  FPSCR_SET_FI(0);
   4519      1.1  christos 	  GOTO(Done);
   4520      1.1  christos 	/**/
   4521      1.1  christos 	LABEL(Infinity_Operand):
   4522      1.1  christos 	  *frT = *frB;
   4523      1.1  christos 	  if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
   4524      1.1  christos 	  if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
   4525      1.1  christos 	  FPSCR_SET_FR(0);
   4526      1.1  christos 	  FPSCR_SET_FI(0);
   4527      1.1  christos 	  GOTO(Done);
   4528      1.1  christos 	/**/
   4529      1.1  christos 	LABEL(QNaN_Operand):
   4530      1.1  christos 	  *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
   4531      1.1  christos 	  FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
   4532      1.1  christos 	  FPSCR_SET_FR(0);
   4533      1.1  christos 	  FPSCR_SET_FI(0);
   4534      1.1  christos 	  GOTO(Done);
   4535      1.1  christos 	/**/
   4536      1.1  christos 	LABEL(SNaN_Operand):
   4537      1.1  christos 	  FPSCR_OR_VX(fpscr_vxsnan);
   4538      1.1  christos 	  if ((FPSCR & fpscr_ve) == 0) {
   4539      1.1  christos 	    *frT = (MASKED64(*frB, 0, 11)
   4540      1.1  christos 	            | BIT64(12)
   4541      1.1  christos 	            | MASKED64(*frB, 13, 34));
   4542      1.1  christos 	    FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
   4543      1.1  christos 	  }
   4544      1.1  christos 	  FPSCR_SET_FR(0);
   4545      1.1  christos 	  FPSCR_SET_FI(0);
   4546      1.1  christos 	  GOTO(Done);
   4547      1.1  christos 	/**/
   4548      1.1  christos 	LABEL(Normal_Operand):
   4549      1.1  christos 	  sign = EXTRACTED64(*frB, 0, 0);
   4550      1.1  christos 	  exp = EXTRACTED64(*frB, 1, 11) - 1023;
   4551      1.1  christos 	  frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
   4552      1.1  christos 	  Round_Single(processor, sign, &exp, &frac_grx);
   4553      1.1  christos 	  FPSCR_SET_XX(FPSCR & fpscr_fi);
   4554      1.1  christos 	  if (exp > 127 && (FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
   4555      1.1  christos 	  if (exp > 127 && (FPSCR & fpscr_oe) != 0) GOTO(Enabled_Overflow);
   4556      1.1  christos 	  *frT = (INSERTED64(sign, 0, 0)
   4557      1.1  christos 	          | INSERTED64(exp + 1023, 1, 11)
   4558      1.1  christos 	          | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
   4559      1.1  christos 	  if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
   4560      1.1  christos 	  if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
   4561      1.1  christos 	  GOTO(Done);
   4562      1.1  christos 	/**/
   4563      1.1  christos 	LABEL(Done):
   4564      1.1  christos 	  PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
   4565      1.1  christos 
   4566      1.1  christos 
   4567      1.1  christos 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
   4568      1.1  christos 	floating_point_assist_interrupt(processor, cia);
   4569      1.1  christos 
   4570      1.1  christos 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
   4571      1.1  christos 	floating_point_assist_interrupt(processor, cia);
   4572      1.1  christos 
   4573      1.1  christos 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
   4574      1.1  christos 	floating_point_assist_interrupt(processor, cia);
   4575      1.1  christos 
   4576      1.1  christos 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
   4577      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   4578      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4579      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4580      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4581      1.1  christos 	FPSCR_BEGIN;
   4582      1.1  christos 	convert_to_integer(processor, cia,
   4583      1.1  christos 	                   frT, *frB,
   4584      1.1  christos 	                   fpscr_rn_round_towards_zero, 32);
   4585      1.1  christos 	FPSCR_END(Rc);
   4586      1.1  christos 	PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
   4587      1.1  christos 
   4588      1.1  christos 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
   4589      1.1  christos 	int sign = EXTRACTED64(*frB, 0, 0);
   4590      1.1  christos 	int exp = 63;
   4591      1.1  christos 	uint64_t frac = *frB;
   4592      1.1  christos 	/***/
   4593      1.1  christos 	  if (frac == 0) GOTO(Zero_Operand);
   4594      1.1  christos 	  if (sign == 1) frac = ~frac + 1;
   4595      1.1  christos 	  while (EXTRACTED64(frac, 0, 0) == 0) {
   4596      1.1  christos 	    /*??? do the loop 0 times if (FRB) = max negative integer */
   4597      1.1  christos 	    frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
   4598      1.1  christos 	    exp = exp - 1;
   4599      1.1  christos 	  }
   4600      1.1  christos 	  Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
   4601      1.1  christos 	  if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
   4602      1.1  christos 	  if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
   4603      1.1  christos 	  *frT = (INSERTED64(sign, 0, 0)
   4604      1.1  christos 	          | INSERTED64(exp + 1023, 1, 11)
   4605      1.1  christos 	          | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
   4606      1.1  christos 	  GOTO(Done);
   4607      1.1  christos 	/**/
   4608      1.1  christos 	LABEL(Zero_Operand):
   4609      1.1  christos 	  FPSCR_SET_FR(0);
   4610      1.1  christos 	  FPSCR_SET_FI(0);
   4611      1.1  christos 	  FPSCR_SET_FPRF(fpscr_rf_pos_zero);
   4612      1.1  christos 	  *frT = 0;
   4613      1.1  christos 	  GOTO(Done);
   4614      1.1  christos 	/**/
   4615      1.1  christos 	LABEL(Done):
   4616      1.1  christos 	  PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
   4617      1.1  christos 
   4618      1.1  christos 
   4619      1.1  christos #
   4620      1.1  christos # I.4.6.7 Floating-Point Compare Instructions
   4621      1.1  christos #
   4622      1.1  christos 
   4623      1.1  christos 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
   4624      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   4625      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4626      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4627      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4628      1.1  christos 	FPSCR_BEGIN;
   4629      1.1  christos 	unsigned c;
   4630      1.1  christos 	if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
   4631      1.1  christos 	  c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
   4632      1.1  christos 	else if (is_less_than(frA, frB))
   4633      1.1  christos 	  c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
   4634      1.1  christos 	else if (is_greater_than(frA, frB))
   4635      1.1  christos 	  c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
   4636      1.1  christos 	else
   4637      1.1  christos 	  c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
   4638      1.1  christos 	FPSCR_SET_FPCC(c);
   4639      1.1  christos 	CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
   4640      1.1  christos 	if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
   4641      1.1  christos 	  FPSCR_OR_VX(fpscr_vxsnan);
   4642      1.1  christos 	FPSCR_END(0);
   4643      1.1  christos 	PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
   4644      1.1  christos 
   4645      1.1  christos 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
   4646      1.1  christos *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
   4647      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4648      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4649      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4650      1.1  christos 	FPSCR_BEGIN;
   4651      1.1  christos 	unsigned c;
   4652      1.1  christos 	if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
   4653      1.1  christos 	  c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
   4654      1.1  christos 	else if (is_less_than(frA, frB))
   4655      1.1  christos 	  c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
   4656      1.1  christos 	else if (is_greater_than(frA, frB))
   4657      1.1  christos 	  c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
   4658      1.1  christos 	else
   4659      1.1  christos 	  c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
   4660      1.1  christos 	FPSCR_SET_FPCC(c);
   4661      1.1  christos 	CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
   4662      1.1  christos 	if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
   4663      1.1  christos 	  FPSCR_OR_VX(fpscr_vxsnan);
   4664      1.1  christos 	  if ((FPSCR & fpscr_ve) == 0)
   4665      1.1  christos 	    FPSCR_OR_VX(fpscr_vxvc);
   4666      1.1  christos 	}
   4667      1.1  christos 	else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
   4668      1.1  christos 	  FPSCR_OR_VX(fpscr_vxvc);
   4669      1.1  christos 	}
   4670      1.1  christos 	FPSCR_END(0);
   4671      1.1  christos 	PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
   4672      1.1  christos 
   4673      1.1  christos 
   4674      1.1  christos #
   4675      1.1  christos # I.4.6.8 Floating-Point Status and Control Register Instructions
   4676      1.1  christos #
   4677      1.1  christos 
   4678      1.1  christos 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
   4679      1.1  christos 	FPSCR_BEGIN;
   4680      1.1  christos 	*frT = FPSCR;
   4681      1.1  christos 	FPSCR_END(Rc);
   4682      1.1  christos 
   4683      1.1  christos 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
   4684      1.1  christos 	FPSCR_BEGIN;
   4685      1.1  christos 	unsigned field = FPSCR_FIELD(BFA);
   4686      1.1  christos 	CR_SET(BF, field);
   4687      1.1  christos 	FPSCR_SET(BFA, 0); /* FPSCR_END fixes up FEX/VX */
   4688      1.1  christos 	FPSCR_END(0);
   4689      1.1  christos 
   4690      1.1  christos 0.63,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
   4691      1.1  christos 	FPSCR_BEGIN;
   4692      1.1  christos 	FPSCR_SET(BF, U);
   4693      1.1  christos 	FPSCR_END(Rc);
   4694      1.1  christos 
   4695      1.1  christos 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
   4696      1.1  christos 	FPSCR_BEGIN;
   4697      1.1  christos 	int i;
   4698      1.1  christos 	for (i = 0; i < 8; i++) {
   4699      1.1  christos 	  if ((FLM & BIT8(i))) {
   4700      1.1  christos 	    FPSCR &= ~MASK32(i*4, i*4+3);
   4701      1.1  christos 	    FPSCR |= MASKED32(*frB, i*4, i*4+3);
   4702      1.1  christos 	  }
   4703      1.1  christos 	}
   4704      1.1  christos 	FPSCR_END(Rc);
   4705      1.1  christos 
   4706      1.1  christos 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
   4707      1.1  christos 	FPSCR_BEGIN;
   4708      1.1  christos 	uint32_t bit = BIT32(BT);
   4709      1.1  christos 	FPSCR &= ~bit;
   4710      1.1  christos 	FPSCR_END(Rc);
   4711      1.1  christos 
   4712      1.1  christos 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
   4713      1.1  christos 	FPSCR_BEGIN;
   4714      1.1  christos 	uint32_t bit = BIT32(BT);
   4715      1.1  christos 	if (bit & fpscr_fi)
   4716      1.1  christos 	  bit |= fpscr_xx;
   4717      1.1  christos 	if ((bit & fpscr_vx_bits))
   4718      1.1  christos 	  bit |= fpscr_fx;
   4719      1.1  christos 	/* note - omit vx bit */
   4720      1.1  christos 	if ((bit & (fpscr_ox | fpscr_ux | fpscr_zx | fpscr_xx)))
   4721      1.1  christos 	  bit |= fpscr_fx;
   4722      1.1  christos 	FPSCR |= bit;
   4723      1.1  christos 	FPSCR_END(Rc);
   4724      1.1  christos 
   4725      1.1  christos #
   4726      1.1  christos # I.A.1.2 Floating-Point Arithmetic Instructions
   4727      1.1  christos #
   4728      1.1  christos 
   4729      1.1  christos 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root
   4730      1.1  christos 	program_interrupt(processor, cia, optional_instruction_program_interrupt);
   4731      1.1  christos 
   4732      1.1  christos 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root Single
   4733      1.1  christos 	program_interrupt(processor, cia, optional_instruction_program_interrupt);
   4734      1.1  christos 
   4735      1.1  christos 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f,o::Floating Reciprocal Estimate Single
   4736      1.1  christos 	program_interrupt(processor, cia, optional_instruction_program_interrupt);
   4737      1.1  christos 
   4738      1.1  christos 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f,o::Floating Reciprocal Square Root Estimate
   4739      1.1  christos 	program_interrupt(processor, cia, optional_instruction_program_interrupt);
   4740      1.1  christos 
   4741      1.1  christos #
   4742      1.1  christos # I.A.1.3 Floating-Point Select Instruction
   4743      1.1  christos #
   4744      1.1  christos 
   4745      1.1  christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f,o::Floating Select
   4746      1.1  christos *601: PPC_UNIT_BAD,   PPC_UNIT_BAD,   0,  0,  0
   4747      1.1  christos *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4748      1.1  christos *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4749      1.1  christos *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
   4750      1.1  christos 	if (CURRENT_MODEL == MODEL_ppc601) {
   4751      1.1  christos 	  program_interrupt(processor, cia, optional_instruction_program_interrupt);
   4752      1.1  christos 	} else {
   4753      1.1  christos 	  uint64_t zero = 0;
   4754      1.1  christos 	  FPSCR_BEGIN;
   4755      1.1  christos 	  if (is_NaN(*frA, 0) || is_less_than (frA, &zero)) *frT = *frB;
   4756      1.1  christos 	  else						    *frT = *frC;
   4757      1.1  christos 	  FPSCR_END(Rc);
   4758      1.1  christos 	  PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
   4759      1.1  christos 	}
   4760      1.1  christos 
   4761      1.1  christos #
   4762      1.1  christos # II.3.2 Cache Management Instructions
   4763      1.1  christos #
   4764      1.1  christos 
   4765      1.1  christos 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
   4766      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4767      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   4768      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   4769      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
   4770      1.1  christos 	/* blindly flush all instruction cache entries */
   4771      1.1  christos 	#if WITH_IDECODE_CACHE_SIZE
   4772      1.1  christos 	cpu_flush_icache(processor);
   4773      1.1  christos 	#endif
   4774      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
   4775      1.1  christos 
   4776      1.1  christos 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
   4777      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4778      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   4779      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   4780      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
   4781      1.1  christos 	cpu_synchronize_context(processor, cia);
   4782      1.1  christos 	PPC_INSN_INT(0, 0, 0);
   4783      1.1  christos 
   4784      1.1  christos 
   4785      1.1  christos #
   4786      1.1  christos # II.3.2.2 Data Cache Instructions
   4787      1.1  christos #
   4788      1.1  christos 
   4789      1.1  christos 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
   4790      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4791      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
   4792      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
   4793      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
   4794      1.1  christos 	TRACE(trace_tbd,("Data Cache Block Touch\n"));
   4795      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
   4796      1.1  christos 
   4797      1.1  christos 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
   4798      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4799      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
   4800      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
   4801      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   4802      1.1  christos 	TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
   4803      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
   4804      1.1  christos 
   4805      1.1  christos 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
   4806      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4807      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   10, 10, 0
   4808      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   10, 10, 0
   4809      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   4810      1.1  christos 	TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
   4811      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
   4812      1.1  christos 
   4813      1.1  christos 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
   4814      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4815      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
   4816      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
   4817      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
   4818      1.1  christos 	TRACE(trace_tbd,("Data Cache Block Store\n"));
   4819      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
   4820      1.1  christos 
   4821      1.1  christos 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
   4822      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4823      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
   4824      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
   4825      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
   4826      1.1  christos 	TRACE(trace_tbd,("Data Cache Block Flush\n"));
   4827      1.1  christos 	PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
   4828      1.1  christos 
   4829      1.1  christos #
   4830      1.1  christos # II.3.3 Enforce In-order Execution of I/O Instruction
   4831      1.1  christos #
   4832      1.1  christos 
   4833      1.1  christos 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
   4834      1.1  christos 	/* Since this model has no instruction overlap
   4835      1.1  christos 	   this instruction need do nothing */
   4836      1.1  christos 
   4837      1.1  christos #
   4838      1.1  christos # II.4.1 Time Base Instructions
   4839      1.1  christos #
   4840      1.1  christos 
   4841      1.1  christos 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
   4842      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   4843      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   4844      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
   4845      1.1  christos 	int n = (tbr{5:9} << 5) | tbr{0:4};
   4846      1.1  christos 	if (n == 268) {
   4847      1.1  christos 	  if (is_64bit_implementation) *rT = TB;
   4848      1.1  christos 	  else                         *rT = EXTRACTED64(TB, 32, 63);
   4849      1.1  christos 	}
   4850      1.1  christos 	else if (n == 269) {
   4851      1.1  christos 	  if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
   4852      1.1  christos 	  else                         *rT = EXTRACTED64(TB, 0, 31);
   4853      1.1  christos 	}
   4854      1.1  christos 	else
   4855      1.1  christos 	  program_interrupt(processor, cia,
   4856      1.1  christos 	                    illegal_instruction_program_interrupt);
   4857      1.1  christos 
   4858      1.1  christos 
   4859      1.1  christos #
   4860      1.1  christos # III.2.3.1 System Linkage Instructions
   4861      1.1  christos #
   4862      1.1  christos 
   4863      1.1  christos 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
   4864      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4865      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
   4866      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
   4867      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
   4868      1.1  christos 	if (IS_PROBLEM_STATE(processor)) {
   4869      1.1  christos 	  program_interrupt(processor, cia,
   4870      1.1  christos 	                    privileged_instruction_program_interrupt);
   4871      1.1  christos 	}
   4872      1.1  christos 	else {
   4873      1.1  christos 	  MSR = (MASKED(SRR1, 0, 32)
   4874      1.1  christos 	         | MASKED(SRR1, 37, 41)
   4875      1.1  christos 	         | MASKED(SRR1, 48, 63));
   4876      1.1  christos 	  NIA = MASKED(SRR0, 0, 61);
   4877      1.1  christos 	  cpu_synchronize_context(processor, cia);
   4878      1.1  christos 	  check_masked_interrupts(processor);
   4879      1.1  christos 	}
   4880      1.1  christos 
   4881      1.1  christos #
   4882      1.1  christos # III.3.4.1 Move to/from System Register Instructions
   4883      1.1  christos #
   4884      1.1  christos 
   4885      1.1  christos #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
   4886      1.1  christos #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
   4887      1.1  christos 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
   4888      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4889      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
   4890      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
   4891      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
   4892      1.1  christos 	if (IS_PROBLEM_STATE(processor))
   4893      1.1  christos 	  program_interrupt(processor, cia,
   4894      1.1  christos 	                    privileged_instruction_program_interrupt);
   4895      1.1  christos 	else {
   4896      1.1  christos 	  MSR = *rS;
   4897      1.1  christos 	  check_masked_interrupts(processor);
   4898      1.1  christos 	}
   4899      1.1  christos 
   4900      1.1  christos 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
   4901      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4902      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   4903      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
   4904      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
   4905      1.1  christos 	if (IS_PROBLEM_STATE(processor))
   4906      1.1  christos 	  program_interrupt(processor, cia,
   4907      1.1  christos 	                    privileged_instruction_program_interrupt);
   4908      1.1  christos 	else {
   4909      1.1  christos 	  *rT = MSR;
   4910      1.1  christos 	  check_masked_interrupts(processor);
   4911      1.1  christos 	}
   4912      1.1  christos 
   4913      1.1  christos 
   4914      1.1  christos #
   4915      1.1  christos # III.4.11.1 Cache Management Instructions
   4916      1.1  christos #
   4917      1.1  christos 
   4918      1.1  christos 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
   4919      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4920      1.1  christos *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
   4921      1.1  christos *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
   4922      1.1  christos *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
   4923      1.1  christos 	if (IS_PROBLEM_STATE(processor))
   4924      1.1  christos 	  program_interrupt(processor, cia,
   4925      1.1  christos 	                    privileged_instruction_program_interrupt);
   4926      1.1  christos 	else
   4927      1.1  christos 	  TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
   4928      1.1  christos 
   4929      1.1  christos #
   4930      1.1  christos # III.4.11.2 Segment Register Manipulation Instructions
   4931      1.1  christos #
   4932      1.1  christos 
   4933      1.1  christos 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
   4934      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4935      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
   4936      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
   4937      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
   4938      1.1  christos 	if (IS_PROBLEM_STATE(processor))
   4939      1.1  christos 	  program_interrupt(processor, cia,
   4940      1.1  christos 	                    privileged_instruction_program_interrupt);
   4941      1.1  christos 	else
   4942      1.1  christos 	  SEGREG(SR) = *rS;
   4943      1.1  christos 
   4944      1.1  christos 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
   4945      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
   4946      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
   4947      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
   4948      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
   4949      1.1  christos 	if (IS_PROBLEM_STATE(processor))
   4950      1.1  christos 	  program_interrupt(processor, cia,
   4951      1.1  christos 	                    privileged_instruction_program_interrupt);
   4952      1.1  christos 	else
   4953      1.1  christos 	  SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
   4954      1.1  christos 
   4955      1.1  christos 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
   4956      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
   4957      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
   4958      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
   4959      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
   4960      1.1  christos 	if (IS_PROBLEM_STATE(processor))
   4961      1.1  christos 	  program_interrupt(processor, cia,
   4962      1.1  christos 	                    privileged_instruction_program_interrupt);
   4963      1.1  christos 	else
   4964      1.1  christos 	  *rT = SEGREG(SR);
   4965      1.1  christos 
   4966      1.1  christos 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
   4967      1.1  christos *601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
   4968      1.1  christos *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
   4969      1.1  christos *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
   4970      1.1  christos *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
   4971      1.1  christos 	if (IS_PROBLEM_STATE(processor))
   4972      1.1  christos 	  program_interrupt(processor, cia,
   4973      1.1  christos 	                    privileged_instruction_program_interrupt);
   4974      1.1  christos 	else
   4975      1.1  christos 	  *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
   4976      1.1  christos 
   4977      1.1  christos 
   4978      1.1  christos #
   4979      1.1  christos # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
   4980      1.1  christos #
   4981      1.1  christos 
   4982      1.1  christos 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
   4983      1.1  christos 
   4984      1.1  christos 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
   4985      1.1  christos 
   4986      1.1  christos 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
   4987      1.1  christos 	if (IS_PROBLEM_STATE(processor))
   4988      1.1  christos 	  program_interrupt(processor, cia,
   4989      1.1  christos 	                    privileged_instruction_program_interrupt);
   4990      1.1  christos 	else {
   4991      1.1  christos 	  int nr = 0;
   4992      1.1  christos 	  cpu *proc;
   4993      1.1  christos 	  while (1) {
   4994      1.1  christos 	    proc = psim_cpu(cpu_system(processor), nr);
   4995      1.1  christos 	    if (proc == NULL) break;
   4996      1.1  christos 	    cpu_page_tlb_invalidate_entry(proc, *rB);
   4997      1.1  christos 	    nr++;
   4998      1.1  christos 	  }
   4999      1.1  christos 	}
   5000      1.1  christos 
   5001      1.1  christos 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
   5002      1.1  christos 	if (IS_PROBLEM_STATE(processor))
   5003      1.1  christos 	  program_interrupt(processor, cia,
   5004      1.1  christos 	                    privileged_instruction_program_interrupt);
   5005      1.1  christos 	else {
   5006      1.1  christos 	  int nr = 0;
   5007      1.1  christos 	  cpu *proc;
   5008      1.1  christos 	  while (1) {
   5009      1.1  christos 	    proc = psim_cpu(cpu_system(processor), nr);
   5010      1.1  christos 	    if (proc == NULL) break;
   5011      1.1  christos 	    cpu_page_tlb_invalidate_all(proc);
   5012      1.1  christos 	    nr++;
   5013      1.1  christos 	  }
   5014      1.1  christos 	}
   5015      1.1  christos 
   5016      1.1  christos 0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
   5017      1.1  christos 	/* nothing happens here - always in sync */
   5018      1.1  christos 
   5019      1.1  christos #
   5020      1.1  christos # III.A.1.2 External Access Instructions
   5021      1.1  christos #
   5022      1.1  christos 
   5023                    0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
   5024                    
   5025                    0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
   5026                    
   5027                    :include:::altivec.igen
   5028                    :include:::e500.igen
   5029