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