Update
[gdb.git] / sim / ppc / ppc-instructions
blob5f3e13319f63cfb0e2d2a840154d55d34896ff20
2 #   This file is part of the program psim.
4 #   Copyright 1994, 1995, 1996, 1997, 2003, 2004 Andrew Cagney
6 #   --
8 #   The pseudo-code that appears below, translated into C, was copied
9 #   by Andrew Cagney of Moss Vale, Australia.
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.
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.
20 #   --
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.
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.
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.
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)
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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;
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         };
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 */
187         #define PPC_NO_SPR      (-1)                    /* flag for no SPR register */
189         /* Return if 1 bit set */
190         #define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0)
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         };
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         };
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         };
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         };
297 # Trace releasing resources
298 void::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)));
337 # Trace making registers busy
338 void::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         }
362 # Trace waiting for registers to become available
363 void::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)));
394 # Advance state to next cycle, releasing any registers allocated
395 void::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;
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;
417               if (WITH_TRACE && ppc_trace[trace_model])
418                 model_trace_release(model_ptr, cur_busy);
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         }
451         busy_tail->next = (model_busy *)0;
452         model_ptr->busy_tail = busy_tail;
453         model_ptr->free_list = free_list;
455 # Mark a function unit as busy, return the busy structure
456 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
457         model_busy *busy;
459         TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
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         }
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;
486 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
487 model_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;
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);
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);
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         }
509 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
510 void::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);
521 # Wait for a CR to become unbusy
522 void::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++;
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         }
536 # Schedule an instruction that takes integer input registers and produces output registers
537 void::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;
541         if ((model_ptr->int_busy & int_mask) != 0) {
542           model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
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);
548             model_ptr->nr_stalls_data++;
549             model_new_cycle(model_ptr);
550           }
551         }
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;
559         if (WITH_TRACE && ppc_trace[trace_model])
560           model_trace_make_busy(model_ptr, out_mask, 0, 0);
562 # Schedule an instruction that takes integer input registers and produces output registers & sets a CR register
563 void::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;
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 */
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);
574             model_ptr->nr_stalls_data++;
575             model_new_cycle(model_ptr);
576           }
577         }
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;
587         if (cr_mask)
588           busy_ptr->nr_writebacks++;
590         if (WITH_TRACE && ppc_trace[trace_model])
591           model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
594 # Schedule an instruction that takes CR input registers and produces output CR registers
595 void::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;
599         if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
600           model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
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);
606             model_ptr->nr_stalls_data++;
607             model_new_cycle(model_ptr);
608           }
609         }
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;
617         if (WITH_TRACE && ppc_trace[trace_model])
618           model_trace_make_busy(model_ptr, 0, 0, out_mask);
621 # Schedule an instruction that takes floating point input registers and produces an output fp register
622 void::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;
626         if ((model_ptr->fp_busy & fp_mask) != 0) {
627           model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
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);
633             model_ptr->nr_stalls_data++;
634             model_new_cycle(model_ptr);
635           }
636         }
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);
646 # Schedule an instruction that takes floating point input registers and produces an output fp register & sets a CR reg
647 void::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;
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 */
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);
658             model_ptr->nr_stalls_data++;
659             model_new_cycle(model_ptr);
660           }
661         }
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);
673 # Schedule an instruction that takes both int/float input registers and produces output int/float registers
674 void::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;
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 */
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);
686             model_ptr->nr_stalls_data++;
687             model_new_cycle(model_ptr);
688           }
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         }
701 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
702 void::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;
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);
709           model_ptr->nr_stalls_data++;
710           model_new_cycle(model_ptr);
711         }
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);
720 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
721 void::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;
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);
728           model_ptr->nr_stalls_data++;
729           model_new_cycle(model_ptr);
730         }
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)));
738 # Schedule a MFCR instruction that moves the CR into an integer regsiter
739 void::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;
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);
747           model_ptr->nr_stalls_data++;
748           model_new_cycle(model_ptr);
749         }
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);
758 # Schedule a MTCR instruction that moves an integer register into the CR
759 void::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;
767         for (f = 0; f < 8; f++) {
768           if (FXM & (0x80 >> f)) {
769             cr_mask |= (1 << f);
770             nr_crs++;
771           }
772         }
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);
778           model_ptr->nr_stalls_data++;
779           model_new_cycle(model_ptr);
780         }
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         }
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);
795 model_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;
811 void::model-function::model_init:model_data *model_ptr
813 void::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);
818 unsigned_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);
824 unsigned_word::model-function::model_get_number_of_cycles:model_data *model_ptr
825         return (model_ptr->nr_cycles);
827 model_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;
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 = "";
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         }
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         }
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         }
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         }
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         }
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         }
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         }
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         }
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         }
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         }
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         }
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";
954         tail->next = (model_print *)0;
955         return head;
957 void::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         }
964 void::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 */
974 void::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++;
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);
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);
996 # Floating point support functions
999 # Convert 32bit single to 64bit double
1000 unsigned64::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;
1041 # Convert 64bit single to 32bit double
1042 unsigned32::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;
1072 # round 64bit double to 64bit but single
1073 void::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);
1110 void::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);
1134 void::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);
1166 # conversion of FP to integer
1167 void::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):;
1287 # extract out raw fields of a FP number
1288 int::function::sign:unsigned64 FRS
1289         return (MASKED64(FRS, 0, 0)
1290                 ? -1
1291                 : 1);
1292 int::function::biased_exp:unsigned64 frs, int single
1293         if (single)
1294           return EXTRACTED64(frs, 1, 8);
1295         else
1296           return EXTRACTED64(frs, 1, 11);
1297 unsigned64::function::fraction:unsigned64 frs, int single
1298         if (single)
1299           return EXTRACTED64(frs, 9, 31);
1300         else
1301           return EXTRACTED64(frs, 12, 63);
1303 # a number?, each of the below return +1 or -1 (based on sign bit)
1304 # if true.
1305 int::function::is_nor:unsigned64 frs, int single
1306         int exp = biased_exp(frs, single);
1307         return (exp >= 1
1308                 && exp <= (single ? 254 : 2046));
1309 int::function::is_zero:unsigned64 FRS
1310         return (MASKED64(FRS, 1, 63) == 0
1311                 ? sign(FRS)
1312                 : 0);
1313 int::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);
1319 int::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);
1325 int::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);
1331 int::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);
1336 int::function::is_QNaN:unsigned64 frs, int single
1337         return (is_NaN(frs, single) && !is_SNaN(frs, single));
1338 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1339         return *(double*)fra < *(double*)frb;
1340 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1341         return *(double*)fra > *(double*)frb;
1342 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1343         return *(double*)fra == *(double*)frb;
1346 # which quiet nan should become the result
1347 unsigned64::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;
1365 # detect invalid operation
1366 int::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;
1422 # handle case of invalid operation
1423 void::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         }
1451 # detect divide by zero
1452 int::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;
1463 # handle case of invalid operation
1464 void::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         }
1492 # 0.0.0.0 Illegal instruction used for kernel mode emulation
1494 0.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);
1500 # I.2.4.1 Branch Instructions
1502 0.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);
1515 0.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         }
1558 0.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         }
1593 0.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         }
1625 # I.2.4.2 System Call Instruction
1627 0.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);
1637 # I.2.4.3 Condition Register Logical Instructions
1639 0.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);
1647 0.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);
1655 0.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);
1663 0.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);
1671 0.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);
1679 0.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);
1687 0.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);
1695 0.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);
1704 # I.2.4.4 Condition Register Field Instruction
1706 0.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);
1716 # I.3.3.2 Fixed-Point Load Instructions
1719 0.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);
1733 0.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);
1746 0.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);
1760 0.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);
1774 0.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);
1787 0.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);
1800 0.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);
1814 0.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);
1828 0.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);
1841 0.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);
1854 0.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);
1868 0.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);
1882 0.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);
1895 0.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);
1908 0.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);
1922 0.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);
1936 0.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);
1944 0.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);
1952 0.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;
1961 0.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);
1969 0.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);
1977 0.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;
1986 0.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;
1998 # I.3.3.3 Fixed-Point Store Instructions
2001 0.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);
2014 0.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);
2027 0.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);
2041 0.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);
2055 0.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);
2068 0.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);
2081 0.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);
2095 0.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);
2109 0.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);
2122 0.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);
2135 0.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);
2149 0.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);
2163 0.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);
2170 0.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);
2177 0.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;
2185 0.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;
2196 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2199 0.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);
2212 0.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);
2225 0.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);
2238 0.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);
2253 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2256 0.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         }
2275 0.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         }
2294 # I.3.3.6 Fixed-Point Move Assist Instructions
2297 0.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         }
2329 0.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         }
2365 0.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         }
2387 0.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         }
2412 # I.3.3.7 Storage Synchronization Instructions
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.
2419 0.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);
2435 0.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);
2447 0.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*/);
2474 0.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*/);
2497 0.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 */
2506 # I.3.3.9 Fixed-Point Arithmetic Instructions
2509 0.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);
2519 0.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);
2529 0.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);
2539 0.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);
2551 0.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*/);
2561 0.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*/);
2571 0.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*/);
2583 0.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);
2593 0.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);
2606 0.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);
2617 0.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);
2629 0.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);
2640 0.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);
2652 0.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);
2662 0.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);
2673 0.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);
2684 0.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*/);
2693 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2695 0.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);
2710 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2712 0.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);
2725 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2727 0.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);
2740 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2742 0.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);
2762 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2764 0.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);
2785 # I.3.3.10 Fixed-Point Compare Instructions
2788 0.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);
2807 0.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);
2830 0.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);
2849 0.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);
2874 # I.3.3.11 Fixed-Point Trap Instructions
2877 0.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         }
2894 0.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);
2910 0.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         }
2927 0.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);
2948 # I.3.3.12 Fixed-Point Logical Instructions
2951 0.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*/);
2961 0.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*/);
2971 0.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*/);
2980 0.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*/);
2989 0.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*/);
2998 0.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*/);
3007 0.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);
3017 0.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);
3027 0.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);
3037 0.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);
3047 0.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);
3057 0.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);
3067 0.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);
3077 0.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);
3087 0.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);
3097 0.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);
3107 0.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);
3115 0.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 */
3126 0.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 */
3144 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
3147 0.30,6.RS,11.RA,16.sh_0_4,21.mb,27.0,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Clear Left
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 */
3157 0.30,6.RS,11.RA,16.sh_0_4,21.me,27.1,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Clear Right
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 */
3166 0.30,6.RS,11.RA,16.sh_0_4,21.mb,27.2,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Clear
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 */
3175 0.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);
3193 0.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);
3202 0.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);
3211 0.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);
3219 0.30,6.RS,11.RA,16.sh_0_4,21.mb,27.3,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Mask Insert
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);
3228 0.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);
3245 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
3247 0.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);
3266 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3268 0.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);
3287 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3289 0.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);
3309 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3311 0.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);
3339 # I.3.3.14 Move to/from System Register Instructions
3342 0.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);
3386 0.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);
3419 0.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);
3438 0.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);
3442 0.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);
3451 # I.4.6.2 Floating-Point Load Instructions
3454 0.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);
3467 0.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);
3480 0.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);
3494 0.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);
3508 0.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);
3521 0.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);
3534 0.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);
3548 0.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);
3564 # I.4.6.3 Floating-Point Store Instructions
3567 0.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);
3580 0.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);
3593 0.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);
3607 0.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);
3621 0.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);
3634 0.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);
3647 0.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);
3659 0.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);
3673 0.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);
3689 # I.4.6.4 Floating-Point Move Instructions
3692 0.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);
3701 0.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);
3710 0.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);
3719 0.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);
3730 # I.4.6.5 Floating-Point Arithmetic Instructions
3733 0.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);
3759 0.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);
3785 0.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);
3811 0.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);
3837 0.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);
3863 0.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);
3889 0.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);
3922 0.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);
3955 0.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);
4000 0.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);
4045 0.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);
4090 0.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);
4135 0.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);
4180 0.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);
4225 0.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);
4270 0.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);
4317 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4320 0.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);
4539 0.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);
4542 0.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);
4545 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4546         floating_point_assist_interrupt(processor, cia);
4548 0.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);
4560 0.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);
4592 # I.4.6.7 Floating-Point Compare Instructions
4595 0.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);
4617 0.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);
4647 # I.4.6.8 Floating-Point Status and Control Register Instructions
4650 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4651         FPSCR_BEGIN;
4652         *frT = FPSCR;
4653         FPSCR_END(Rc);
4655 0.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);
4662 0.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);
4667 0.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);
4678 0.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);
4684 0.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);
4698 # I.A.1.2 Floating-Point Arithmetic Instructions
4701 0.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);
4704 0.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);
4707 0.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);
4710 0.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);
4714 # I.A.1.3 Floating-Point Select Instruction
4717 0.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         }
4734 # II.3.2 Cache Management Instructions
4737 0.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);
4748 0.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);
4758 # II.3.2.2 Data Cache Instructions
4761 0.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*/);
4769 0.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*/);
4777 0.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*/);
4785 0.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*/);
4793 0.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*/);
4802 # II.3.3 Enforce In-order Execution of I/O Instruction
4805 0.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 */
4810 # II.4.1 Time Base Instructions
4813 0.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);
4832 # III.2.3.1 System Linkage Instructions
4835 0.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         }
4854 # III.3.4.1 Move to/from System Register Instructions
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
4859 0.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         }
4872 0.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         }
4887 # III.4.11.1 Cache Management Instructions
4890 0.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"));
4902 # III.4.11.2 Segment Register Manipulation Instructions
4905 0.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;
4916 0.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;
4927 0.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);
4938 0.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));
4951 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4954 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4956 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4958 0.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         }
4973 0.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         }
4988 0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
4989         /* nothing happens here - always in sync */
4992 # III.A.1.2 External Access Instructions
4995 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4997 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
4999 :include:::altivec.igen
5000 :include:::e500.igen