run copyright.sh for 2011.
[external/binutils.git] / sim / ppc / ppc-instructions
1 #
2 #   This file is part of the program psim.
3 #
4 #   Copyright 1994, 1995, 1996, 1997, 2003, 2004 Andrew Cagney
5 #
6 #   --
7 #
8 #   The pseudo-code that appears below, translated into C, was copied
9 #   by Andrew Cagney of Moss Vale, Australia.
10 #
11 #   This pseudo-code is copied by permission from the publication
12 #   "The PowerPC Architecture: A Specification for A New Family of
13 #   RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by
14 #   International Business Machines Corporation.
15 #
16 #   THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER
17 #   EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES
18 #   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 #
20 #   --
21 #
22 #   This program is free software; you can redistribute it and/or modify
23 #   it under the terms of the GNU General Public License as published by
24 #   the Free Software Foundation; either version 2 of the License, or
25 #   (at your option) any later version.
26 #
27 #   This program is distributed in the hope that it will be useful,
28 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
29 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30 #   GNU General Public License for more details.
31 #
32 #   You should have received a copy of the GNU General Public License
33 #   along with this program; if not, write to the Free Software
34 #   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #
36
37 :cache::::RA:RA:
38 :cache:::signed_word *:rA:RA:(cpu_registers(processor)->gpr + RA)
39 :cache:::unsigned32:RA_BITMASK:RA:(1 << RA)
40 :compute:::int:RA_is_0:RA:(RA == 0)
41 :cache::::RT:RT:
42 :cache:::signed_word *:rT:RT:(cpu_registers(processor)->gpr + RT)
43 :cache:::unsigned32:RT_BITMASK:RT:(1 << RT)
44 :cache::::RS:RS:
45 :cache:::signed_word *:rS:RS:(cpu_registers(processor)->gpr + RS)
46 :cache:::unsigned32:RS_BITMASK:RS:(1 << RS)
47 :cache::::RB:RB:
48 :cache:::signed_word *:rB:RB:(cpu_registers(processor)->gpr + RB)
49 :cache:::unsigned32:RB_BITMASK:RB:(1 << RB)
50 :scratch::::FRA:FRA:
51 :cache:::unsigned64 *:frA:FRA:(cpu_registers(processor)->fpr + FRA)
52 :cache:::unsigned32:FRA_BITMASK:FRA:(1 << FRA)
53 :scratch::::FRB:FRB:
54 :cache:::unsigned64 *:frB:FRB:(cpu_registers(processor)->fpr + FRB)
55 :cache:::unsigned32:FRB_BITMASK:FRB:(1 << FRB)
56 :scratch::::FRC:FRC:
57 :cache:::unsigned64 *:frC:FRC:(cpu_registers(processor)->fpr + FRC)
58 :cache:::unsigned32:FRC_BITMASK:FRC:(1 << FRC)
59 :scratch::::FRS:FRS:
60 :cache:::unsigned64 *:frS:FRS:(cpu_registers(processor)->fpr + FRS)
61 :cache:::unsigned32:FRS_BITMASK:FRS:(1 << FRS)
62 :scratch::::FRT:FRT:
63 :cache:::unsigned64 *:frT:FRT:(cpu_registers(processor)->fpr + FRT)
64 :cache:::unsigned32:FRT_BITMASK:FRT:(1 << FRT)
65 :cache:::unsigned_word:EXTS_SI:SI:((signed_word)(signed16)instruction)
66 :scratch::::BI:BI:
67 :cache::::BIT32_BI:BI:BIT32(BI)
68 :cache::::BF:BF:
69 :cache:::unsigned32:BF_BITMASK:BF:(1 << BF)
70 :scratch::::BA:BA:
71 :cache::::BIT32_BA:BA:BIT32(BA)
72 :cache:::unsigned32:BA_BITMASK:BA:(1 << BA)
73 :scratch::::BB:BB:
74 :cache::::BIT32_BB:BB:BIT32(BB)
75 :cache:::unsigned32:BB_BITMASK:BB:(1 << BB)
76 :cache::::BT:BT:
77 :cache:::unsigned32:BT_BITMASK:BT:(1 << BT)
78 :cache:::unsigned_word:EXTS_BD_0b00:BD:(((signed_word)(signed16)instruction) & ~3)
79 :cache:::unsigned_word:EXTS_LI_0b00:LI:((((signed_word)(signed32)(instruction << 6)) >> 6) & ~0x3)
80 :cache:::unsigned_word:EXTS_D:D:((signed_word)(signed16)(instruction))
81 :cache:::unsigned_word:EXTS_DS_0b00:DS:(((signed_word)(signed16)instruction) & ~0x3)
82 #:compute:::int:SPR_is_256:SPR:(SPR == 256)
83 \f
84 # PowerPC models
85 ::model:604:ppc604:  PPC_UNIT_BAD,   PPC_UNIT_BAD,   1,  1,  0
86 ::model:603e:ppc603e:PPC_UNIT_BAD,   PPC_UNIT_BAD,   1,  1,  0
87 ::model:603:ppc603:  PPC_UNIT_BAD,   PPC_UNIT_BAD,   1,  1,  0
88 ::model:601:ppc601:  PPC_UNIT_BAD,   PPC_UNIT_BAD,   1,  1,  0
89
90 # Flags for model.h
91 ::model-macro:::
92         #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \
93                 do { \
94                   if (CURRENT_MODEL_ISSUE > 0) { \
95                     if (RC) \
96                       ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
97                     else \
98                       ppc_insn_int(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
99                   } \
100                 } while (0)
101
102         #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \
103                 do { \
104                   if (CURRENT_MODEL_ISSUE > 0) \
105                     ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
106                 } while (0)
107
108         #define PPC_INSN_CR(OUT_MASK, IN_MASK) \
109                 do { \
110                   if (CURRENT_MODEL_ISSUE > 0) \
111                     ppc_insn_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
112                 } while (0)
113
114         #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \
115                 do { \
116                   if (CURRENT_MODEL_ISSUE > 0) { \
117                     if (RC) \
118                       ppc_insn_float(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
119                     else \
120                       ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
121                   } \
122                 } while (0)
123
124         #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \
125                 do { \
126                   if (CURRENT_MODEL_ISSUE > 0) \
127                     ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
128                 } while (0)
129
130         #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \
131                 do { \
132                   if (CURRENT_MODEL_ISSUE > 0) \
133                     ppc_insn_int_float(MY_INDEX, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \
134                 } while (0)
135
136         #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \
137                 do { \
138                   if (CURRENT_MODEL_ISSUE > 0) \
139                     ppc_insn_from_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
140                 } while (0)
141
142         #define PPC_INSN_TO_SPR(INT_MASK, SPR) \
143                 do { \
144                   if (CURRENT_MODEL_ISSUE > 0) \
145                     ppc_insn_to_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
146                 } while (0)
147
148         #define PPC_INSN_MFCR(INT_MASK) \
149                 do { \
150                   if (CURRENT_MODEL_ISSUE > 0) \
151                     ppc_insn_mfcr(MY_INDEX, cpu_model(processor), INT_MASK); \
152                 } while (0)
153
154         #define PPC_INSN_MTCR(INT_MASK, FXM) \
155                 do { \
156                   if (CURRENT_MODEL_ISSUE > 0) \
157                     ppc_insn_mtcr(MY_INDEX, cpu_model(processor), INT_MASK, FXM); \
158                 } while (0)
159
160 ::model-data:::
161         typedef enum _ppc_function_unit {
162           PPC_UNIT_BAD,                         /* unknown function unit */
163           PPC_UNIT_IU,                          /* integer unit (601/603 style) */
164           PPC_UNIT_SRU,                         /* system register unit (601/603 style) */
165           PPC_UNIT_SCIU1,                       /* 1st single cycle integer unit (604 style) */
166           PPC_UNIT_SCIU2,                       /* 2nd single cycle integer unit (604 style) */
167           PPC_UNIT_MCIU,                        /* multiple cycle integer unit (604 style) */
168           PPC_UNIT_FPU,                         /* floating point unit */
169           PPC_UNIT_LSU,                         /* load/store unit */
170           PPC_UNIT_BPU,                         /* branch unit */
171           nr_ppc_function_units
172         } ppc_function_unit;
173
174         /* Structure to hold timing information on a per instruction basis */
175         struct _model_time {
176           ppc_function_unit first_unit;                 /* first functional unit this insn could use */
177           ppc_function_unit second_unit;                /* second functional unit this insn could use */
178           signed16          issue;                      /* # cycles before function unit can process other insns */
179           signed16          done;                       /* # cycles before insn is done */
180           unsigned32        flags;                      /* any flags that are needed */
181         };
182
183         /* Register mappings in status masks */
184         #define PPC_CR_REG      0                       /* start of CR0 .. CR7 */
185         #define PPC_FPSCR_REG   (PPC_CR_REG + 8)        /* start of fpscr register */
186
187         #define PPC_NO_SPR      (-1)                    /* flag for no SPR register */
188
189         /* Return if 1 bit set */
190         #define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0)
191
192         /* Structure for each functional unit that is busy */
193         typedef struct _model_busy model_busy;
194         struct _model_busy {
195           model_busy *next;                             /* next function unit */
196           ppc_function_unit unit;                       /* function unit name */
197           unsigned32 int_busy;                          /* int registers that are busy */
198           unsigned32 fp_busy;                           /* floating point registers that are busy */
199           unsigned32 cr_fpscr_busy;                     /* CR/FPSCR registers that are busy */
200           signed16 spr_busy;                            /* SPR register that is busy or PPC_NO_SPR */
201           unsigned32 vr_busy;                           /* AltiVec registers that are busy */
202           signed16 vscr_busy;                           /* AltiVec status register busy */
203           signed16 issue;                               /* # of cycles until unit can accept another insn */
204           signed16 done;                                /* # of cycles until insn is done */
205           signed16 nr_writebacks;                       /* # of registers this unit writes back */
206         };
207         
208         /* Structure to hold the current state information for the simulated CPU model */
209         struct _model_data {
210           cpu *processor;                               /* point back to processor */
211           const char *name;                             /* model name */
212           const model_time *timing;                     /* timing information */
213           model_busy busy_head;                         /* dummy entry to head list of busy function units */
214           model_busy *busy_tail;                        /* tail of list of busy function units */
215           model_busy *free_list;                        /* list of model_busy structs not in use */
216           count_type nr_cycles;                         /* # cycles */
217           count_type nr_branches;                       /* # branches */
218           count_type nr_branches_fallthrough;           /* # conditional branches that fell through */
219           count_type nr_branch_predict_trues;           /* # branches predicted correctly */
220           count_type nr_branch_predict_falses;          /* # branches predicted incorrectly */
221           count_type nr_branch_conditional[32];         /* # of each type of bc */
222           count_type nr_mtcrf_crs[9];                   /* # of CR's moved in a mtcrf instruction */
223           count_type nr_stalls_data;                    /* # of stalls for data */
224           count_type nr_stalls_unit;                    /* # of stalls waiting for a function unit */
225           count_type nr_stalls_serialize;               /* # of stalls waiting for things to quiet down */
226           count_type nr_stalls_writeback;               /* # of stalls waiting for a writeback slot */
227           count_type nr_units[nr_ppc_function_units];   /* function unit counts */
228           int max_nr_writebacks;                        /* max # of writeback slots available */
229           unsigned32 int_busy;                          /* int registers that are busy */
230           unsigned32 fp_busy;                           /* floating point registers that are busy */
231           unsigned32 cr_fpscr_busy;                     /* CR/FPSCR registers that are busy */
232           unsigned8 spr_busy[nr_of_sprs];               /* SPR registers that are busy */
233           unsigned32 vr_busy;                           /* AltiVec registers that are busy */
234           unsigned8 vscr_busy;                          /* AltiVec SC register busy */
235           unsigned8 busy[nr_ppc_function_units];        /* whether a function is busy or not */
236         };
237
238         static const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
239           "unknown functional unit instruction",
240           "integer functional unit instruction",
241           "system register functional unit instruction",
242           "1st single cycle integer functional unit instruction",
243           "2nd single cycle integer functional unit instruction",
244           "multiple cycle integer functional unit instruction",
245           "floating point functional unit instruction",
246           "load/store functional unit instruction",
247           "branch functional unit instruction",
248         };
249
250         static const char *const ppc_branch_conditional_name[32] = {
251           "branch if --CTR != 0 and condition is FALSE",                                /* 0000y */
252           "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
253           "branch if --CTR == 0 and condition is FALSE",                                /* 0001y */
254           "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
255           "branch if the condition is FALSE",                                           /* 001zy */
256           "branch if the condition is FALSE, reverse branch likely",
257           "branch if the condition is FALSE (ignored bit 1 set to 1)",                  /* 001zy */
258           "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
259           "branch if --CTR != 0 and condition is TRUE",                                 /* 0100y */
260           "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
261           "branch if --CTR == 0 and condition is TRUE",                                 /* 0101y */
262           "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
263           "branch if the condition is TRUE",                                            /* 011zy */
264           "branch if the condition is TRUE, reverse branch likely",
265           "branch if the condition is TRUE (ignored bit 1 set to 1)",                   /* 011zy */
266           "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
267           "branch if --CTR != 0",                                                       /* 1z00y */
268           "branch if --CTR != 0, reverse branch likely",
269           "branch if --CTR == 0",                                                       /* 1z01y */
270           "branch if --CTR == 0, reverse branch likely",
271           "branch always",                                                              /* 1z1zz */
272           "branch always (ignored bit 5 set to 1)",
273           "branch always (ignored bit 4 set to 1)",                                     /* 1z1zz */
274           "branch always (ignored bits 4,5 set to 1)",
275           "branch if --CTR != 0 (ignored bit 1 set to 1)",                              /* 1z00y */
276           "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
277           "branch if --CTR == 0 (ignored bit 1 set to 1)",                              /* 1z01y */
278           "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
279           "branch always (ignored bit 1 set to 1)",                                     /* 1z1zz */
280           "branch always (ignored bits 1,5 set to 1)",
281           "branch always (ignored bits 1,4 set to 1)",                                  /* 1z1zz */
282           "branch always (ignored bits 1,4,5 set to 1)",
283         };
284
285         static const char *const ppc_nr_mtcrf_crs[9] = {
286           "mtcrf moving 0 CRs",
287           "mtcrf moving 1 CR",
288           "mtcrf moving 2 CRs",
289           "mtcrf moving 3 CRs",
290           "mtcrf moving 4 CRs",
291           "mtcrf moving 5 CRs",
292           "mtcrf moving 6 CRs",
293           "mtcrf moving 7 CRs",
294           "mtcrf moving all CRs",
295         };
296 \f
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)));
336
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         }
361
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)));
393 \f
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;
401
402         model_ptr->nr_cycles++;
403         TRACE(trace_model,("New cycle %lu\n", (unsigned long)model_ptr->nr_cycles));
404         for ( ; cur_busy; cur_busy = next) {
405           next = cur_busy->next;
406           if (--cur_busy->done <= 0) {          /* function unit done, release registers if we have writeback slots */
407             nr_writebacks -= cur_busy->nr_writebacks;
408             if (nr_writebacks >= 0) {
409               model_ptr->int_busy &= ~cur_busy->int_busy;
410               model_ptr->fp_busy &= ~cur_busy->fp_busy;
411               model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
412               if (cur_busy->spr_busy != PPC_NO_SPR)
413                 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
414               model_ptr->vr_busy &= ~cur_busy->vr_busy;
415               model_ptr->vscr_busy = ~cur_busy->vscr_busy;
416
417               if (WITH_TRACE && ppc_trace[trace_model])
418                 model_trace_release(model_ptr, cur_busy);
419
420               model_ptr->busy[cur_busy->unit] = 0;
421               cur_busy->next = free_list;
422               free_list = cur_busy;
423             }
424             else {      /* writeback slots not available */
425               TRACE(trace_model,("%d writeback slot%s not available for %s\n",
426                                  cur_busy->nr_writebacks,
427                                  cur_busy->nr_writebacks == 1 ? " is" : "s are",
428                                  ppc_function_unit_name[cur_busy->unit]));
429               cur_busy->done++;                 /* undo -- above */
430               model_ptr->nr_stalls_writeback++;
431               busy_tail->next = cur_busy;
432               busy_tail = cur_busy;
433             }
434           }
435           else if (--cur_busy->issue <= 0) {    /* function unit pipelined, allow new use */
436             TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
437             model_ptr->busy[cur_busy->unit] = 0;
438             busy_tail->next = cur_busy;
439             busy_tail = cur_busy;
440           }
441           else {
442             TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
443                                ppc_function_unit_name[cur_busy->unit],
444                                cur_busy->issue,
445                                cur_busy->done));
446             busy_tail->next = cur_busy;
447             busy_tail = cur_busy;
448           }
449         }
450
451         busy_tail->next = (model_busy *)0;
452         model_ptr->busy_tail = busy_tail;
453         model_ptr->free_list = free_list;
454
455 # Mark a function unit as busy, return the busy structure
456 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
457         model_busy *busy;
458
459         TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
460
461         if (!model_ptr->free_list) {
462           busy = ZALLOC(model_busy);
463         }
464         else {
465           busy = model_ptr->free_list;
466           model_ptr->free_list = busy->next;
467           busy->next = (model_busy *)0;
468           busy->int_busy = 0;
469           busy->fp_busy = 0;
470           busy->cr_fpscr_busy = 0;
471           busy->nr_writebacks = 0;
472           busy->vr_busy = 0;
473           busy->vscr_busy = 0;
474         }
475
476         busy->unit = unit;
477         busy->issue = issue;
478         busy->done = done;
479         busy->spr_busy = PPC_NO_SPR;
480         model_ptr->busy_tail->next = busy;
481         model_ptr->busy_tail = busy;
482         model_ptr->busy[unit] = 1;
483         model_ptr->nr_units[unit]++;
484         return busy;
485 \f
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;
491
492         for (;;) {
493           if (!model_ptr->busy[first_unit])
494             return model_make_busy(model_ptr, first_unit,
495                                    model_ptr->timing[index].issue,
496                                    model_ptr->timing[index].done);
497
498           if (!model_ptr->busy[second_unit])
499             return model_make_busy(model_ptr, second_unit,
500                                    model_ptr->timing[index].issue,
501                                    model_ptr->timing[index].done);
502
503           TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
504           model_ptr->nr_stalls_unit += stall_increment;         /* don't count first stall */
505           stall_increment = 1;
506           model_new_cycle(model_ptr);
507         }
508
509 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
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);
520
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++;
528
529         cr_mask = (1 << cr_var);
530         while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
531           TRACE(trace_model,("waiting for CR %d\n", cr_var));
532           model_ptr->nr_stalls_data++;
533           model_new_cycle(model_ptr);
534         }
535
536 # Schedule an instruction that takes integer input registers and produces output registers
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;
540
541         if ((model_ptr->int_busy & int_mask) != 0) {
542           model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
543
544           while ((model_ptr->int_busy & int_mask) != 0) {
545             if (WITH_TRACE && ppc_trace[trace_model])
546               model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
547
548             model_ptr->nr_stalls_data++;
549             model_new_cycle(model_ptr);
550           }
551         }
552
553         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
554         model_ptr->int_busy |= out_mask;
555         busy_ptr->int_busy |= out_mask;
556         if (out_mask)
557           busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
558
559         if (WITH_TRACE && ppc_trace[trace_model])
560           model_trace_make_busy(model_ptr, out_mask, 0, 0);
561
562 # Schedule an instruction that takes integer input registers and produces output registers & sets a CR register
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;
566
567         if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
568           model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
569
570           while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
571             if (WITH_TRACE && ppc_trace[trace_model])
572               model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
573
574             model_ptr->nr_stalls_data++;
575             model_new_cycle(model_ptr);
576           }
577         }
578
579         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
580         model_ptr->int_busy |= out_mask;
581         busy_ptr->int_busy |= out_mask;
582         model_ptr->cr_fpscr_busy |= cr_mask;
583         busy_ptr->cr_fpscr_busy |= cr_mask;
584         if (out_mask)
585           busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
586
587         if (cr_mask)
588           busy_ptr->nr_writebacks++;
589
590         if (WITH_TRACE && ppc_trace[trace_model])
591           model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
592
593
594 # Schedule an instruction that takes CR input registers and produces output CR registers
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;
598
599         if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
600           model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
601
602           while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
603             if (WITH_TRACE && ppc_trace[trace_model])
604               model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
605
606             model_ptr->nr_stalls_data++;
607             model_new_cycle(model_ptr);
608           }
609         }
610
611         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
612         model_ptr->cr_fpscr_busy |= out_mask;
613         busy_ptr->cr_fpscr_busy |= out_mask;
614         if (out_mask)
615           busy_ptr->nr_writebacks = 1;
616
617         if (WITH_TRACE && ppc_trace[trace_model])
618           model_trace_make_busy(model_ptr, 0, 0, out_mask);
619
620
621 # Schedule an instruction that takes floating point input registers and produces an output fp register
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;
625
626         if ((model_ptr->fp_busy & fp_mask) != 0) {
627           model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
628
629           while ((model_ptr->fp_busy & fp_mask) != 0) {
630             if (WITH_TRACE && ppc_trace[trace_model])
631               model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
632
633             model_ptr->nr_stalls_data++;
634             model_new_cycle(model_ptr);
635           }
636         }
637
638         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
639         model_ptr->fp_busy |= out_mask;
640         busy_ptr->fp_busy |= out_mask;
641         busy_ptr->nr_writebacks = 1;
642         if (WITH_TRACE && ppc_trace[trace_model])
643           model_trace_make_busy(model_ptr, 0, out_mask, 0);
644
645
646 # Schedule an instruction that takes floating point input registers and produces an output fp register & sets a CR reg
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;
650
651         if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
652           model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
653
654           while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
655             if (WITH_TRACE && ppc_trace[trace_model])
656               model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
657
658             model_ptr->nr_stalls_data++;
659             model_new_cycle(model_ptr);
660           }
661         }
662
663         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
664         model_ptr->fp_busy |= out_mask;
665         busy_ptr->fp_busy |= out_mask;
666         model_ptr->cr_fpscr_busy |= cr_mask;
667         busy_ptr->cr_fpscr_busy |= cr_mask;
668         busy_ptr->nr_writebacks = (cr_mask) ? 2 : 1;
669         if (WITH_TRACE && ppc_trace[trace_model])
670           model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
671
672
673 # Schedule an instruction that takes both int/float input registers and produces output int/float registers
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;
678
679         if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
680           model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
681
682           while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
683             if (WITH_TRACE && ppc_trace[trace_model])
684               model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
685
686             model_ptr->nr_stalls_data++;
687             model_new_cycle(model_ptr);
688           }
689
690           busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
691           model_ptr->int_busy |= out_int_mask;
692           busy_ptr->int_busy |= out_int_mask;
693           model_ptr->fp_busy |= out_fp_mask;
694           busy_ptr->fp_busy |= out_fp_mask;
695           busy_ptr->nr_writebacks = ((out_int_mask) ? 1 : 0) + ((out_fp_mask) ? 1 : 0);
696           if (WITH_TRACE && ppc_trace[trace_model])
697             model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0);
698           return;
699         }
700
701 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
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;
704
705         while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
706           if (WITH_TRACE && ppc_trace[trace_model])
707             model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
708
709           model_ptr->nr_stalls_data++;
710           model_new_cycle(model_ptr);
711         }
712
713         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
714         model_ptr->int_busy |= int_mask;
715         busy_ptr->int_busy |= int_mask;
716         busy_ptr->nr_writebacks = 1;
717         if (WITH_TRACE && ppc_trace[trace_model])
718           model_trace_make_busy(model_ptr, int_mask, 0, 0);
719
720 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
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;
723
724         while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
725           if (WITH_TRACE && ppc_trace[trace_model])
726             model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
727
728           model_ptr->nr_stalls_data++;
729           model_new_cycle(model_ptr);
730         }
731
732         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
733         busy_ptr->spr_busy = nSPR;
734         model_ptr->spr_busy[nSPR] = 1;
735         busy_ptr->nr_writebacks = 1;
736         TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));
737
738 # Schedule a MFCR instruction that moves the CR into an integer regsiter
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;
742
743         while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
744           if (WITH_TRACE && ppc_trace[trace_model])
745             model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
746
747           model_ptr->nr_stalls_data++;
748           model_new_cycle(model_ptr);
749         }
750
751         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
752         model_ptr->int_busy |= int_mask;
753         busy_ptr->int_busy |= int_mask;
754         busy_ptr->nr_writebacks = 1;
755         if (WITH_TRACE && ppc_trace[trace_model])
756           model_trace_make_busy(model_ptr, int_mask, 0, 0);
757
758 # Schedule a MTCR instruction that moves an integer register into the CR
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;
766
767         for (f = 0; f < 8; f++) {
768           if (FXM & (0x80 >> f)) {
769             cr_mask |= (1 << f);
770             nr_crs++;
771           }
772         }
773
774         while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
775           if (WITH_TRACE && ppc_trace[trace_model])
776             model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
777
778           model_ptr->nr_stalls_data++;
779           model_new_cycle(model_ptr);
780         }
781
782         /* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */
783         if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) {
784           normal_time = &ppc604_1bit_time;
785         }
786
787         busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
788         busy_ptr->cr_fpscr_busy |= cr_mask;
789         model_ptr->cr_fpscr_busy |= cr_mask;
790         model_ptr->nr_mtcrf_crs[nr_crs]++;
791         busy_ptr->nr_writebacks = 1;
792         if (WITH_TRACE && ppc_trace[trace_model])
793           model_trace_make_busy(model_ptr, 0, 0, cr_mask);
794 \f
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;
810
811 void::model-function::model_init:model_data *model_ptr
812
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);
817
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);
823
824 unsigned_word::model-function::model_get_number_of_cycles:model_data *model_ptr
825         return (model_ptr->nr_cycles);
826
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;
833
834         head = tail = ZALLOC(model_print);
835         tail->count = model_ptr->nr_cycles;
836         tail->name = "cycle";
837         tail->suffix_plural = "s";
838         tail->suffix_singular = "";
839
840         if (model_ptr->nr_stalls_data) {
841           tail->next = ZALLOC(model_print);
842           tail = tail->next;
843           tail->count = model_ptr->nr_stalls_data;
844           tail->name = "stall";
845           tail->suffix_plural = "s waiting for data";
846           tail->suffix_singular = " waiting for data";
847         }
848
849         if (model_ptr->nr_stalls_unit) {
850           tail->next = ZALLOC(model_print);
851           tail = tail->next;
852           tail->count = model_ptr->nr_stalls_unit;
853           tail->name = "stall";
854           tail->suffix_plural = "s waiting for a function unit";
855           tail->suffix_singular = " waiting for a function unit";
856         }
857
858         if (model_ptr->nr_stalls_serialize) {
859           tail->next = ZALLOC(model_print);
860           tail = tail->next;
861           tail->count = model_ptr->nr_stalls_serialize;
862           tail->name = "stall";
863           tail->suffix_plural = "s waiting for serialization";
864           tail->suffix_singular = " waiting for serialization";
865         }
866
867         if (model_ptr->nr_stalls_writeback) {
868           tail->next = ZALLOC(model_print);
869           tail = tail->next;
870           tail->count = model_ptr->nr_stalls_writeback;
871           tail->name = "";
872           tail->suffix_plural = "times a write-back slot was unavailable";
873           tail->suffix_singular = "time a writeback was unavailable";
874         }
875
876         if (model_ptr->nr_branches) {
877           tail->next = ZALLOC(model_print);
878           tail = tail->next;
879           tail->count = model_ptr->nr_branches;
880           tail->name = "branch";
881           tail->suffix_plural = "es";
882           tail->suffix_singular = "";
883         }
884
885         if (model_ptr->nr_branches_fallthrough) {
886           tail->next = ZALLOC(model_print);
887           tail = tail->next;
888           tail->count = model_ptr->nr_branches_fallthrough;
889           tail->name = "conditional branch";
890           tail->suffix_plural = "es fell through";
891           tail->suffix_singular = " fell through";
892         }
893
894         if (model_ptr->nr_branch_predict_trues) {
895           tail->next = ZALLOC(model_print);
896           tail = tail->next;
897           tail->count = model_ptr->nr_branch_predict_trues;
898           tail->name = "successful branch prediction";
899           tail->suffix_plural = "s";
900           tail->suffix_singular = "";
901         }
902
903         if (model_ptr->nr_branch_predict_falses) {
904           tail->next = ZALLOC(model_print);
905           tail = tail->next;
906           tail->count = model_ptr->nr_branch_predict_falses;
907           tail->name = "unsuccessful branch prediction";
908           tail->suffix_plural = "s";
909           tail->suffix_singular = "";
910         }
911
912         for (j = 0; j < (sizeof(ppc_branch_conditional_name) / sizeof(ppc_branch_conditional_name[0])) ; j++) {
913           if (model_ptr->nr_branch_conditional[j]) {
914             tail->next = ZALLOC(model_print);
915             tail = tail->next;
916             tail->count = model_ptr->nr_branch_conditional[j];
917             tail->name = ppc_branch_conditional_name[j];
918             tail->suffix_plural = " conditional branches";
919             tail->suffix_singular = " conditional branch";
920           }
921         }
922
923         for (j = 0; j < 9; j++) {
924           if (model_ptr->nr_mtcrf_crs[j]) {
925             tail->next = ZALLOC(model_print);
926             tail = tail->next;
927             tail->count = model_ptr->nr_mtcrf_crs[j];
928             tail->name = ppc_nr_mtcrf_crs[j];
929             tail->suffix_plural = " instructions";
930             tail->suffix_singular = " instruction";
931           }
932         }
933
934         nr_insns = 0;
935         for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
936           if (model_ptr->nr_units[i]) {
937             nr_insns += model_ptr->nr_units[i];
938             tail->next = ZALLOC(model_print);
939             tail = tail->next;
940             tail->count = model_ptr->nr_units[i];
941             tail->name = ppc_function_unit_name[i];
942             tail->suffix_plural = "s";
943             tail->suffix_singular = "";
944           }
945         }
946
947         tail->next = ZALLOC(model_print);
948         tail = tail->next;
949         tail->count = nr_insns;
950         tail->name = "instruction";
951         tail->suffix_plural = "s that were accounted for in timing info";
952         tail->suffix_singular = " that was accounted for in timing info";
953
954         tail->next = (model_print *)0;
955         return head;
956
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         }
963
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 */
973
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++;
979
980 \f
981 # The following (illegal) instruction is `known' by gen and is
982 # called when ever an illegal instruction is encountered
983 ::internal::illegal
984         program_interrupt(processor, cia,
985                           illegal_instruction_program_interrupt);
986
987
988 # The following (floating point unavailable) instruction is `known' by gen
989 # and is called when ever an a floating point instruction is to be
990 # executed but floating point is make unavailable by the MSR
991 ::internal::floating_point_unavailable
992         floating_point_unavailable_interrupt(processor, cia);
993
994
995 #
996 # Floating point support functions
997 #
998
999 # Convert 32bit single to 64bit double
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;
1040
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;
1070
1071
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);
1107
1108
1109 #
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);
1132
1133
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);
1164
1165
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):;
1285
1286
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);
1302
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;
1344
1345
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;
1363
1364
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;
1417
1418
1419
1420
1421
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         }
1447
1448
1449
1450
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;
1459
1460
1461
1462
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         }
1486
1487
1488
1489
1490
1491 #
1492 # 0.0.0.0 Illegal instruction used for kernel mode emulation
1493 #
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);
1498
1499 #
1500 # I.2.4.1 Branch Instructions
1501 #
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);
1514
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         }
1557
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         }
1592
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         }
1623
1624 #
1625 # I.2.4.2 System Call Instruction
1626 #
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);
1635
1636 #
1637 # I.2.4.3 Condition Register Logical Instructions
1638 #
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);
1646
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);
1654
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);
1662
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);
1670
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);
1678
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);
1686
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);
1694
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);
1702
1703 #
1704 # I.2.4.4 Condition Register Field Instruction
1705 #
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);
1713
1714
1715 #
1716 # I.3.3.2 Fixed-Point Load Instructions
1717 #
1718
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);
1731
1732
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);
1745
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);
1759
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);
1773
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);
1786
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);
1799
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);
1813
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);
1827
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);
1840
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);
1853
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);
1867
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);
1881
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);
1894
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);
1907
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);
1921
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);
1935
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);
1943
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);
1951
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;
1960
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);
1968
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);
1976
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;
1985
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;
1994
1995
1996
1997 #
1998 # I.3.3.3 Fixed-Point Store Instructions
1999 #
2000
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);
2013
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);
2026
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);
2040
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);
2054
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);
2067
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);
2080
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);
2094
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);
2108
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);
2121
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);
2134
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);
2148
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);
2162
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;
2193
2194
2195 #
2196 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2197 #
2198
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);
2211
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);
2224
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);
2237
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);
2250
2251
2252 #
2253 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2254 #
2255
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         }
2274
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         }
2291
2292
2293 #
2294 # I.3.3.6 Fixed-Point Move Assist Instructions
2295 #
2296
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         }
2328
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         }
2364
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         }
2386
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         }
2409
2410
2411 #
2412 # I.3.3.7 Storage Synchronization Instructions
2413 #
2414 # HACK: Rather than monitor addresses looking for a reason
2415 #       to cancel a reservation.  This code instead keeps
2416 #       a copy of the data read from memory.  Before performing
2417 #       a store, the memory area is checked to see if it has
2418 #       been changed.
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);
2434
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);
2446
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*/);
2473
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*/);
2496
2497 0.31,6./,9.L,11./,16./,21.598,31./:X::sync:Synchronize
2498 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
2499 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
2500 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
2501 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
2502         /* do nothing */
2503
2504
2505 #
2506 # I.3.3.9 Fixed-Point Arithmetic Instructions
2507 #
2508
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);
2518
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);
2528
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);
2538
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);
2550
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*/);
2560
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*/);
2570
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*/);
2582
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);
2592
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);
2605
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);
2616
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);
2628
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);
2639
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);
2651
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);
2661
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);
2672
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);
2683
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*/);
2692
2693 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2694
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);
2709
2710 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2711
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);
2724
2725 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2726
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);
2739
2740 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2741
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);
2761
2762 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2763
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);
2782
2783
2784 #
2785 # I.3.3.10 Fixed-Point Compare Instructions
2786 #
2787
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);
2806
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);
2829
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);
2848
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);
2871
2872
2873 #
2874 # I.3.3.11 Fixed-Point Trap Instructions
2875 #
2876
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         }
2893
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);
2909
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         }
2926
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);
2946
2947 #
2948 # I.3.3.12 Fixed-Point Logical Instructions
2949 #
2950
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*/);
2960
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*/);
2970
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*/);
2979
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*/);
2988
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*/);
2997
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*/);
3006
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);
3016
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);
3026
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);
3036
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);
3046
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);
3056
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);
3066
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);
3076
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);
3086
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);
3096
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);
3106
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);
3114
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 */
3125
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 */
3141
3142
3143 #
3144 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
3145 #
3146
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 */
3156
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 */
3165
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 */
3174
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);
3192
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);
3201
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);
3210
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);
3218
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);
3227
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);
3243
3244
3245 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
3246
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);
3265
3266 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3267
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);
3286
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
3288
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);
3308
3309 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3310
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);
3337
3338 #
3339 # I.3.3.14 Move to/from System Register Instructions
3340 #
3341
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);
3385
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_tbrl:
3406                   if (is_64bit_implementation) *rT = TB;
3407                   else                         *rT = EXTRACTED64(TB, 32, 63);
3408                 break;
3409                 case spr_tbru:
3410                   if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
3411                   else                         *rT = EXTRACTED64(TB, 0, 31);
3412                 break;
3413             case spr_tbu:
3414             case spr_tbl:
3415               /* NOTE - these SPR's are not readable. Use mftb[ul] */
3416             default:
3417               *rT = SPREG(n);
3418               break;
3419             }
3420           }
3421           else {
3422             *rT = SPREG(n);
3423           }
3424         }
3425         PPC_INSN_FROM_SPR(RT_BITMASK, n);
3426
3427 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3428 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
3429 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
3430 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
3431 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
3432         if (FXM == 0xff) {
3433           CR = *rS;
3434         }
3435         else {
3436           unsigned_word mask = 0;
3437           unsigned_word f;
3438           for (f = 0; f < 8; f++) {
3439             if (FXM & (0x80 >> f))
3440               mask |= (0xf << 4*(7-f));
3441           }
3442           CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3443         }
3444         PPC_INSN_MTCR(RS_BITMASK, FXM);
3445
3446 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3447 #       CR_SET(BF, EXTRACTED32(XER, 0, 3));
3448 #       MBLIT32(XER, 0, 3, 0);
3449
3450 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3451 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3452 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
3453 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
3454 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
3455         *rT = (unsigned32)CR;
3456         PPC_INSN_MFCR(RT_BITMASK);
3457
3458 #
3459 # I.4.6.2 Floating-Point Load Instructions
3460 #
3461
3462 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3463 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3464 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3465 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3466 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3467         unsigned_word b;
3468         unsigned_word EA;
3469         if (RA_is_0) b = 0;
3470         else         b = *rA;
3471         EA = b + EXTS(D);
3472         *frT = DOUBLE(MEM(unsigned, EA, 4));
3473         PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3474
3475 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3476 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3477 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3478 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3479 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3480         unsigned_word b;
3481         unsigned_word EA;
3482         if (RA_is_0) b = 0;
3483         else         b = *rA;
3484         EA = b + *rB;
3485         *frT = DOUBLE(MEM(unsigned, EA, 4));
3486         PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3487
3488 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3489 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3490 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3491 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3492 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3493         unsigned_word EA;
3494         if (RA_is_0)
3495           program_interrupt(processor, cia,
3496                             illegal_instruction_program_interrupt);
3497         EA = *rA + EXTS(D);
3498         *frT = DOUBLE(MEM(unsigned, EA, 4));
3499         *rA = EA;
3500         PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3501
3502 0.31,6.FRT,11.RA,16.RB,21.567,31./:X:f::Load Floating-Point Single with Update Indexed
3503 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3504 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3505 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3506 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3507         unsigned_word EA;
3508         if (RA_is_0)
3509           program_interrupt(processor, cia,
3510                             illegal_instruction_program_interrupt);
3511         EA = *rA + *rB;
3512         *frT = DOUBLE(MEM(unsigned, EA, 4));
3513         *rA = EA;
3514         PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3515
3516 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3517 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3518 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3519 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3520 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3521         unsigned_word b;
3522         unsigned_word EA;
3523         if (RA_is_0) b = 0;
3524         else         b = *rA;
3525         EA = b + EXTS(D);
3526         *frT = MEM(unsigned, EA, 8);
3527         PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3528
3529 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3530 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3531 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3532 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3533 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3534         unsigned_word b;
3535         unsigned_word EA;
3536         if (RA_is_0) b = 0;
3537         else         b = *rA;
3538         EA = b + *rB;
3539         *frT = MEM(unsigned, EA, 8);
3540         PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3541
3542 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3543 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3544 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3545 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3546 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3547         unsigned_word EA;
3548         if (RA_is_0)
3549           program_interrupt(processor, cia,
3550                             illegal_instruction_program_interrupt);
3551         EA = *rA + EXTS(D);
3552         *frT = MEM(unsigned, EA, 8);
3553         *rA = EA;
3554         PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3555
3556 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3557 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3558 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3559 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3560 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3561         unsigned_word EA;
3562         if (RA_is_0)
3563           program_interrupt(processor, cia,
3564                             illegal_instruction_program_interrupt);
3565         EA = *rA + *rB;
3566         *frT = MEM(unsigned, EA, 8);
3567         *rA = EA;
3568         PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3569
3570
3571 #
3572 # I.4.6.3 Floating-Point Store Instructions
3573 #
3574
3575 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3576 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3577 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3578 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3579 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3580         unsigned_word b;
3581         unsigned_word EA;
3582         if (RA_is_0) b = 0;
3583         else         b = *rA;
3584         EA = b + EXTS(D);
3585         STORE(EA, 4, SINGLE(*frS));
3586         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3587
3588 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3589 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3590 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3591 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3592 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3593         unsigned_word b;
3594         unsigned_word EA;
3595         if (RA_is_0) b = 0;
3596         else         b = *rA;
3597         EA = b + *rB;
3598         STORE(EA, 4, SINGLE(*frS));
3599         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3600
3601 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3602 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3603 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3604 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3605 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3606         unsigned_word EA;
3607         if (RA_is_0)
3608           program_interrupt(processor, cia,
3609                             illegal_instruction_program_interrupt);
3610         EA = *rA + EXTS(D);
3611         STORE(EA, 4, SINGLE(*frS));
3612         *rA = EA;
3613         PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3614
3615 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3616 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3617 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3618 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3619 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3620         unsigned_word EA;
3621         if (RA_is_0)
3622           program_interrupt(processor, cia,
3623                             illegal_instruction_program_interrupt);
3624         EA = *rA + *rB;
3625         STORE(EA, 4, SINGLE(*frS));
3626         *rA = EA;
3627         PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3628
3629 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3630 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3631 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3632 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3633 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3634         unsigned_word b;
3635         unsigned_word EA;
3636         if (RA_is_0) b = 0;
3637         else         b = *rA;
3638         EA = b + EXTS(D);
3639         STORE(EA, 8, *frS);
3640         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3641
3642 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3643 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3644 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3645 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3646 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3647         unsigned_word b;
3648         unsigned_word EA;
3649         if (RA_is_0) b = 0;
3650         else         b = *rA;
3651         EA = b + *rB;
3652         STORE(EA, 8, *frS);
3653         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3654
3655 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point Integer Word Indexed
3656 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3657 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3658 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3659         unsigned_word b;
3660         unsigned_word EA;
3661         if (RA_is_0) b = 0;
3662         else         b = *rA;
3663         EA = b + *rB;
3664         STORE(EA, 4, *frS);
3665         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3666
3667 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3668 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3669 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3670 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3671 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3672         unsigned_word EA;
3673         if (RA_is_0)
3674           program_interrupt(processor, cia,
3675                             illegal_instruction_program_interrupt);
3676         EA = *rA + EXTS(D);
3677         STORE(EA, 8, *frS);
3678         *rA = EA;
3679         PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3680
3681 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3682 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3683 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3684 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3685 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3686         unsigned_word EA;
3687         if (RA_is_0)
3688           program_interrupt(processor, cia,
3689                             illegal_instruction_program_interrupt);
3690         EA = *rA + *rB;
3691         STORE(EA, 8, *frS);
3692         *rA = EA;
3693         PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3694
3695
3696 #
3697 # I.4.6.4 Floating-Point Move Instructions
3698 #
3699
3700 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3701 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3702 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3703 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3704 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3705         *frT = *frB;
3706         CR1_UPDATE(Rc);
3707         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3708
3709 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3710 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3711 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3712 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3713 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3714         *frT = *frB ^ BIT64(0);
3715         CR1_UPDATE(Rc);
3716         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3717
3718 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3719 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3720 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3721 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3722 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3723         *frT = *frB & ~BIT64(0);
3724         CR1_UPDATE(Rc);
3725         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3726
3727 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3728 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3729 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3730 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3731 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3732         *frT = *frB | BIT64(0);
3733         CR1_UPDATE(Rc);
3734         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3735
3736
3737 #
3738 # I.4.6.5 Floating-Point Arithmetic Instructions
3739 #
3740
3741 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3742 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3743 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3744 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3745 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3746         FPSCR_BEGIN;
3747         if (is_invalid_operation(processor, cia,
3748                                  *frA, *frB,
3749                                  fpscr_vxsnan | fpscr_vxisi,
3750                                  0, /*single?*/
3751                                  0) /*negate?*/) {
3752           invalid_arithemetic_operation(processor, cia,
3753                                         frT, *frA, *frB, 0,
3754                                         0, /*instruction_is_frsp*/
3755                                         0, /*instruction_is_convert_to_64bit*/
3756                                         0, /*instruction_is_convert_to_32bit*/
3757                                         0); /*single-precision*/
3758         }
3759         else {
3760           /*HACK!*/
3761           double s = *(double*)frA + *(double*)frB;
3762           *(double*)frT = s;
3763         }
3764         FPSCR_END(Rc);
3765         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3766
3767 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3768 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3769 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3770 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3771 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3772         FPSCR_BEGIN;
3773         if (is_invalid_operation(processor, cia,
3774                                  *frA, *frB,
3775                                  fpscr_vxsnan | fpscr_vxisi,
3776                                  1, /*single?*/
3777                                  0) /*negate?*/) {
3778           invalid_arithemetic_operation(processor, cia,
3779                                         frT, *frA, *frB, 0,
3780                                         0, /*instruction_is_frsp*/
3781                                         0, /*instruction_is_convert_to_64bit*/
3782                                         0, /*instruction_is_convert_to_32bit*/
3783                                         1); /*single-precision*/
3784         }
3785         else {
3786           /*HACK!*/
3787           float s = *(double*)frA + *(double*)frB;
3788           *(double*)frT = s;
3789         }
3790         FPSCR_END(Rc);
3791         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3792
3793 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3794 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3795 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3796 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3797 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3798         FPSCR_BEGIN;
3799         if (is_invalid_operation(processor, cia,
3800                                  *frA, *frB,
3801                                  fpscr_vxsnan | fpscr_vxisi,
3802                                  0, /*single?*/
3803                                  1) /*negate?*/) {
3804           invalid_arithemetic_operation(processor, cia,
3805                                         frT, *frA, *frB, 0,
3806                                         0, /*instruction_is_frsp*/
3807                                         0, /*instruction_is_convert_to_64bit*/
3808                                         0, /*instruction_is_convert_to_32bit*/
3809                                         0); /*single-precision*/
3810         }
3811         else {
3812           /*HACK!*/
3813           double s = *(double*)frA - *(double*)frB;
3814           *(double*)frT = s;
3815         }
3816         FPSCR_END(Rc);
3817         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3818
3819 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3820 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3821 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3822 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3823 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3824         FPSCR_BEGIN;
3825         if (is_invalid_operation(processor, cia,
3826                                  *frA, *frB,
3827                                  fpscr_vxsnan | fpscr_vxisi,
3828                                  1, /*single?*/
3829                                  1) /*negate?*/) {
3830           invalid_arithemetic_operation(processor, cia,
3831                                         frT, *frA, *frB, 0,
3832                                         0, /*instruction_is_frsp*/
3833                                         0, /*instruction_is_convert_to_64bit*/
3834                                         0, /*instruction_is_convert_to_32bit*/
3835                                         1); /*single-precision*/
3836         }
3837         else {
3838           /*HACK!*/
3839           float s = *(double*)frA - *(double*)frB;
3840           *(double*)frT = s;
3841         }
3842         FPSCR_END(Rc);
3843         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3844
3845 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3846 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
3847 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3848 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3849 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3850         FPSCR_BEGIN;
3851         if (is_invalid_operation(processor, cia,
3852                                  *frA, *frC,
3853                                  fpscr_vxsnan | fpscr_vximz,
3854                                  0, /*single?*/
3855                                  0) /*negate?*/) {
3856           invalid_arithemetic_operation(processor, cia,
3857                                         frT, *frA, 0, *frC,
3858                                         0, /*instruction_is_frsp*/
3859                                         0, /*instruction_is_convert_to_64bit*/
3860                                         0, /*instruction_is_convert_to_32bit*/
3861                                         0); /*single-precision*/
3862         }
3863         else {
3864           /*HACK!*/
3865           double s = *(double*)frA * *(double*)frC;
3866           *(double*)frT = s;
3867         }
3868         FPSCR_END(Rc);
3869         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3870
3871 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3872 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3873 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3874 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3875 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3876         FPSCR_BEGIN;
3877         if (is_invalid_operation(processor, cia,
3878                                  *frA, *frC,
3879                                  fpscr_vxsnan | fpscr_vximz,
3880                                  1, /*single?*/
3881                                  0) /*negate?*/) {
3882           invalid_arithemetic_operation(processor, cia,
3883                                         frT, *frA, 0, *frC,
3884                                         0, /*instruction_is_frsp*/
3885                                         0, /*instruction_is_convert_to_64bit*/
3886                                         0, /*instruction_is_convert_to_32bit*/
3887                                         1); /*single-precision*/
3888         }
3889         else {
3890           /*HACK!*/
3891           float s = *(double*)frA * *(double*)frC;
3892           *(double*)frT = s;
3893         }
3894         FPSCR_END(Rc);
3895         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3896
3897 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3898 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   31, 31, 0
3899 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   33, 33, 0
3900 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   33, 33, 0
3901 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   32, 32, 0
3902         FPSCR_BEGIN;
3903         if (is_invalid_operation(processor, cia,
3904                                  *frA, *frB,
3905                                  fpscr_vxsnan | fpscr_vxzdz,
3906                                  0, /*single?*/
3907                                  0) /*negate?*/) {
3908           invalid_arithemetic_operation(processor, cia,
3909                                         frT, *frA, *frB, 0,
3910                                         0, /*instruction_is_frsp*/
3911                                         0, /*instruction_is_convert_to_64bit*/
3912                                         0, /*instruction_is_convert_to_32bit*/
3913                                         0); /*single-precision*/
3914         }
3915         else if (is_invalid_zero_divide (processor, cia,
3916                                          *frA, *frB,
3917                                          0 /*single?*/)) {
3918           invalid_zero_divide_operation (processor, cia,
3919                                          frT, *frA, *frB,
3920                                          0 /*single?*/);
3921         }
3922         else {
3923           /*HACK!*/
3924           double s = *(double*)frA / *(double*)frB;
3925           *(double*)frT = s;
3926         }
3927         FPSCR_END(Rc);
3928         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3929
3930 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3931 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   17, 17, 0
3932 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
3933 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
3934 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
3935         FPSCR_BEGIN;
3936         if (is_invalid_operation(processor, cia,
3937                                  *frA, *frB,
3938                                  fpscr_vxsnan | fpscr_vxzdz,
3939                                  1, /*single?*/
3940                                  0) /*negate?*/) {
3941           invalid_arithemetic_operation(processor, cia,
3942                                         frT, *frA, *frB, 0,
3943                                         0, /*instruction_is_frsp*/
3944                                         0, /*instruction_is_convert_to_64bit*/
3945                                         0, /*instruction_is_convert_to_32bit*/
3946                                         1); /*single-precision*/
3947         }
3948         else if (is_invalid_zero_divide (processor, cia,
3949                                          *frA, *frB,
3950                                          1 /*single?*/)) {
3951           invalid_zero_divide_operation (processor, cia,
3952                                          frT, *frA, *frB,
3953                                          1 /*single?*/);
3954         }
3955         else {
3956           /*HACK!*/
3957           float s = *(double*)frA / *(double*)frB;
3958           *(double*)frT = s;
3959         }
3960         FPSCR_END(Rc);
3961         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3962
3963 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3964 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
3965 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3966 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3967 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3968         FPSCR_BEGIN;
3969         double product; /*HACK! - incorrectly loosing precision ... */
3970         /* compute the multiply */
3971         if (is_invalid_operation(processor, cia,
3972                                  *frA, *frC,
3973                                  fpscr_vxsnan | fpscr_vximz,
3974                                  0, /*single?*/
3975                                  0) /*negate?*/) {
3976           union { double d; unsigned64 u; } tmp;
3977           invalid_arithemetic_operation(processor, cia,
3978                                         &tmp.u, *frA, 0, *frC,
3979                                         0, /*instruction_is_frsp*/
3980                                         0, /*instruction_is_convert_to_64bit*/
3981                                         0, /*instruction_is_convert_to_32bit*/
3982                                         0); /*single-precision*/
3983           product = tmp.d;
3984         }
3985         else {
3986           /*HACK!*/
3987           product = *(double*)frA * *(double*)frC;
3988         }
3989         /* compute the add */
3990         if (is_invalid_operation(processor, cia,
3991                                  product, *frB,
3992                                  fpscr_vxsnan | fpscr_vxisi,
3993                                  0, /*single?*/
3994                                  0) /*negate?*/) {
3995           invalid_arithemetic_operation(processor, cia,
3996                                         frT, product, *frB, 0,
3997                                         0, /*instruction_is_frsp*/
3998                                         0, /*instruction_is_convert_to_64bit*/
3999                                         0, /*instruction_is_convert_to_32bit*/
4000                                         0); /*single-precision*/
4001         }
4002         else {
4003           /*HACK!*/
4004           double s = product + *(double*)frB;
4005           *(double*)frT = s;
4006         }
4007         FPSCR_END(Rc);
4008         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4009
4010 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
4011 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4012 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4013 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4014 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4015         FPSCR_BEGIN;
4016         float product; /*HACK! - incorrectly loosing precision ... */
4017         /* compute the multiply */
4018         if (is_invalid_operation(processor, cia,
4019                                  *frA, *frC,
4020                                  fpscr_vxsnan | fpscr_vximz,
4021                                  1, /*single?*/
4022                                  0) /*negate?*/) {
4023           union { double d; unsigned64 u; } tmp;
4024           invalid_arithemetic_operation(processor, cia,
4025                                         &tmp.u, *frA, 0, *frC,
4026                                         0, /*instruction_is_frsp*/
4027                                         0, /*instruction_is_convert_to_64bit*/
4028                                         0, /*instruction_is_convert_to_32bit*/
4029                                         0); /*single-precision*/
4030           product = tmp.d;
4031         }
4032         else {
4033           /*HACK!*/
4034           product = *(double*)frA * *(double*)frC;
4035         }
4036         /* compute the add */
4037         if (is_invalid_operation(processor, cia,
4038                                  product, *frB,
4039                                  fpscr_vxsnan | fpscr_vxisi,
4040                                  1, /*single?*/
4041                                  0) /*negate?*/) {
4042           invalid_arithemetic_operation(processor, cia,
4043                                         frT, product, *frB, 0,
4044                                         0, /*instruction_is_frsp*/
4045                                         0, /*instruction_is_convert_to_64bit*/
4046                                         0, /*instruction_is_convert_to_32bit*/
4047                                         0); /*single-precision*/
4048         }
4049         else {
4050           /*HACK!*/
4051           float s = product + *(double*)frB;
4052           *(double*)frT = (double)s;
4053         }
4054         FPSCR_END(Rc);
4055         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4056
4057 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
4058 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
4059 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4060 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4061 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4062         FPSCR_BEGIN;
4063         double product; /*HACK! - incorrectly loosing precision ... */
4064         /* compute the multiply */
4065         if (is_invalid_operation(processor, cia,
4066                                  *frA, *frC,
4067                                  fpscr_vxsnan | fpscr_vximz,
4068                                  0, /*single?*/
4069                                  0) /*negate?*/) {
4070           union { double d; unsigned64 u; } tmp;
4071           invalid_arithemetic_operation(processor, cia,
4072                                         &tmp.u, *frA, 0, *frC,
4073                                         0, /*instruction_is_frsp*/
4074                                         0, /*instruction_is_convert_to_64bit*/
4075                                         0, /*instruction_is_convert_to_32bit*/
4076                                         0); /*single-precision*/
4077           product = tmp.d;
4078         }
4079         else {
4080           /*HACK!*/
4081           product = *(double*)frA * *(double*)frC;
4082         }
4083         /* compute the subtract */
4084         if (is_invalid_operation(processor, cia,
4085                                  product, *frB,
4086                                  fpscr_vxsnan | fpscr_vxisi,
4087                                  0, /*single?*/
4088                                  0) /*negate?*/) {
4089           invalid_arithemetic_operation(processor, cia,
4090                                         frT, product, *frB, 0,
4091                                         0, /*instruction_is_frsp*/
4092                                         0, /*instruction_is_convert_to_64bit*/
4093                                         0, /*instruction_is_convert_to_32bit*/
4094                                         0); /*single-precision*/
4095         }
4096         else {
4097           /*HACK!*/
4098           double s = product - *(double*)frB;
4099           *(double*)frT = s;
4100         }
4101         FPSCR_END(Rc);
4102         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4103
4104 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
4105 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4106 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4107 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4108 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4109         FPSCR_BEGIN;
4110         float product; /*HACK! - incorrectly loosing precision ... */
4111         /* compute the multiply */
4112         if (is_invalid_operation(processor, cia,
4113                                  *frA, *frC,
4114                                  fpscr_vxsnan | fpscr_vximz,
4115                                  1, /*single?*/
4116                                  0) /*negate?*/) {
4117           union { double d; unsigned64 u; } tmp;
4118           invalid_arithemetic_operation(processor, cia,
4119                                         &tmp.u, *frA, 0, *frC,
4120                                         0, /*instruction_is_frsp*/
4121                                         0, /*instruction_is_convert_to_64bit*/
4122                                         0, /*instruction_is_convert_to_32bit*/
4123                                         0); /*single-precision*/
4124           product = tmp.d;
4125         }
4126         else {
4127           /*HACK!*/
4128           product = *(double*)frA * *(double*)frC;
4129         }
4130         /* compute the subtract */
4131         if (is_invalid_operation(processor, cia,
4132                                  product, *frB,
4133                                  fpscr_vxsnan | fpscr_vxisi,
4134                                  1, /*single?*/
4135                                  0) /*negate?*/) {
4136           invalid_arithemetic_operation(processor, cia,
4137                                         frT, product, *frB, 0,
4138                                         0, /*instruction_is_frsp*/
4139                                         0, /*instruction_is_convert_to_64bit*/
4140                                         0, /*instruction_is_convert_to_32bit*/
4141                                         0); /*single-precision*/
4142         }
4143         else {
4144           /*HACK!*/
4145           float s = product - *(double*)frB;
4146           *(double*)frT = (double)s;
4147         }
4148         FPSCR_END(Rc);
4149         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4150
4151 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
4152 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
4153 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4154 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4155 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4156         FPSCR_BEGIN;
4157         double product; /*HACK! - incorrectly loosing precision ... */
4158         /* compute the multiply */
4159         if (is_invalid_operation(processor, cia,
4160                                  *frA, *frC,
4161                                  fpscr_vxsnan | fpscr_vximz,
4162                                  0, /*single?*/
4163                                  0) /*negate?*/) {
4164           union { double d; unsigned64 u; } tmp;
4165           invalid_arithemetic_operation(processor, cia,
4166                                         &tmp.u, *frA, 0, *frC,
4167                                         0, /*instruction_is_frsp*/
4168                                         0, /*instruction_is_convert_to_64bit*/
4169                                         0, /*instruction_is_convert_to_32bit*/
4170                                         0); /*single-precision*/
4171           product = tmp.d;
4172         }
4173         else {
4174           /*HACK!*/
4175           product = *(double*)frA * *(double*)frC;
4176         }
4177         /* compute the add */
4178         if (is_invalid_operation(processor, cia,
4179                                  product, *frB,
4180                                  fpscr_vxsnan | fpscr_vxisi,
4181                                  0, /*single?*/
4182                                  0) /*negate?*/) {
4183           invalid_arithemetic_operation(processor, cia,
4184                                         frT, product, *frB, 0,
4185                                         0, /*instruction_is_frsp*/
4186                                         0, /*instruction_is_convert_to_64bit*/
4187                                         0, /*instruction_is_convert_to_32bit*/
4188                                         0); /*single-precision*/
4189         }
4190         else {
4191           /*HACK!*/
4192           double s = -(product + *(double*)frB);
4193           *(double*)frT = s;
4194         }
4195         FPSCR_END(Rc);
4196         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4197
4198 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
4199 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4200 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4201 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4202 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4203         FPSCR_BEGIN;
4204         float product; /*HACK! - incorrectly loosing precision ... */
4205         /* compute the multiply */
4206         if (is_invalid_operation(processor, cia,
4207                                  *frA, *frC,
4208                                  fpscr_vxsnan | fpscr_vximz,
4209                                  1, /*single?*/
4210                                  0) /*negate?*/) {
4211           union { double d; unsigned64 u; } tmp;
4212           invalid_arithemetic_operation(processor, cia,
4213                                         &tmp.u, *frA, 0, *frC,
4214                                         0, /*instruction_is_frsp*/
4215                                         0, /*instruction_is_convert_to_64bit*/
4216                                         0, /*instruction_is_convert_to_32bit*/
4217                                         0); /*single-precision*/
4218           product = tmp.d;
4219         }
4220         else {
4221           /*HACK!*/
4222           product = *(double*)frA * *(double*)frC;
4223         }
4224         /* compute the add */
4225         if (is_invalid_operation(processor, cia,
4226                                  product, *frB,
4227                                  fpscr_vxsnan | fpscr_vxisi,
4228                                  1, /*single?*/
4229                                  0) /*negate?*/) {
4230           invalid_arithemetic_operation(processor, cia,
4231                                         frT, product, *frB, 0,
4232                                         0, /*instruction_is_frsp*/
4233                                         0, /*instruction_is_convert_to_64bit*/
4234                                         0, /*instruction_is_convert_to_32bit*/
4235                                         0); /*single-precision*/
4236         }
4237         else {
4238           /*HACK!*/
4239           float s = -(product + *(double*)frB);
4240           *(double*)frT = (double)s;
4241         }
4242         FPSCR_END(Rc);
4243         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4244
4245 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
4246 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
4247 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4248 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4249 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4250         FPSCR_BEGIN;
4251         double product; /*HACK! - incorrectly loosing precision ... */
4252         /* compute the multiply */
4253         if (is_invalid_operation(processor, cia,
4254                                  *frA, *frC,
4255                                  fpscr_vxsnan | fpscr_vximz,
4256                                  0, /*single?*/
4257                                  0) /*negate?*/) {
4258           union { double d; unsigned64 u; } tmp;
4259           invalid_arithemetic_operation(processor, cia,
4260                                         &tmp.u, *frA, 0, *frC,
4261                                         0, /*instruction_is_frsp*/
4262                                         0, /*instruction_is_convert_to_64bit*/
4263                                         0, /*instruction_is_convert_to_32bit*/
4264                                         0); /*single-precision*/
4265           product = tmp.d;
4266         }
4267         else {
4268           /*HACK!*/
4269           product = *(double*)frA * *(double*)frC;
4270         }
4271         /* compute the subtract */
4272         if (is_invalid_operation(processor, cia,
4273                                  product, *frB,
4274                                  fpscr_vxsnan | fpscr_vxisi,
4275                                  0, /*single?*/
4276                                  0) /*negate?*/) {
4277           invalid_arithemetic_operation(processor, cia,
4278                                         frT, product, *frB, 0,
4279                                         0, /*instruction_is_frsp*/
4280                                         0, /*instruction_is_convert_to_64bit*/
4281                                         0, /*instruction_is_convert_to_32bit*/
4282                                         0); /*single-precision*/
4283         }
4284         else {
4285           /*HACK!*/
4286           double s = -(product - *(double*)frB);
4287           *(double*)frT = s;
4288         }
4289         FPSCR_END(Rc);
4290         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4291
4292 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
4293 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4294 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4295 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4296 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4297         FPSCR_BEGIN;
4298         float product; /*HACK! - incorrectly loosing precision ... */
4299         /* compute the multiply */
4300         if (is_invalid_operation(processor, cia,
4301                                  *frA, *frC,
4302                                  fpscr_vxsnan | fpscr_vximz,
4303                                  1, /*single?*/
4304                                  0) /*negate?*/) {
4305           union { double d; unsigned64 u; } tmp;
4306           invalid_arithemetic_operation(processor, cia,
4307                                         &tmp.u, *frA, 0, *frC,
4308                                         0, /*instruction_is_frsp*/
4309                                         0, /*instruction_is_convert_to_64bit*/
4310                                         0, /*instruction_is_convert_to_32bit*/
4311                                         0); /*single-precision*/
4312           product = tmp.d;
4313         }
4314         else {
4315           /*HACK!*/
4316           product = *(double*)frA * *(double*)frC;
4317         }
4318         /* compute the subtract */
4319         if (is_invalid_operation(processor, cia,
4320                                  product, *frB,
4321                                  fpscr_vxsnan | fpscr_vxisi,
4322                                  1, /*single?*/
4323                                  0) /*negate?*/) {
4324           invalid_arithemetic_operation(processor, cia,
4325                                         frT, product, *frB, 0,
4326                                         0, /*instruction_is_frsp*/
4327                                         0, /*instruction_is_convert_to_64bit*/
4328                                         0, /*instruction_is_convert_to_32bit*/
4329                                         0); /*single-precision*/
4330         }
4331         else {
4332           /*HACK!*/
4333           float s = -(product - *(double*)frB);
4334           *(double*)frT = (double)s;
4335         }
4336         FPSCR_END(Rc);
4337         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4338
4339
4340 #
4341 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4342 #
4343
4344 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4345 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4346 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4347 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4348 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4349         int sign;
4350         int exp;
4351         unsigned64 frac_grx;
4352         /***/
4353           /* split off cases for what to do */
4354           if (EXTRACTED64(*frB, 1, 11) < 897
4355               && EXTRACTED64(*frB, 1, 63) > 0) {
4356               if ((FPSCR & fpscr_ue) == 0) GOTO(Disabled_Exponent_Underflow);
4357               if ((FPSCR & fpscr_ue) != 0) GOTO(Enabled_Exponent_Underflow);
4358           }
4359           if (EXTRACTED64(*frB, 1, 11) > 1150
4360               && EXTRACTED64(*frB, 1, 11) < 2047) {
4361               if ((FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4362               if ((FPSCR & fpscr_oe) != 0) GOTO(Enabled_Exponent_Overflow);
4363           }
4364           if (EXTRACTED64(*frB, 1, 11) > 896
4365               && EXTRACTED64(*frB, 1, 11) < 1151) GOTO(Normal_Operand);
4366           if (EXTRACTED64(*frB, 1, 63) == 0) GOTO(Zero_Operand);
4367           if (EXTRACTED64(*frB, 1, 11) == 2047) {
4368             if (EXTRACTED64(*frB, 12, 63) == 0) GOTO(Infinity_Operand);
4369             if (EXTRACTED64(*frB, 12, 12) == 1) GOTO(QNaN_Operand);
4370             if (EXTRACTED64(*frB, 12, 12) == 0
4371                 && EXTRACTED64(*frB, 13, 63) > 0) GOTO(SNaN_Operand);
4372           }
4373         /**/
4374         LABEL(Disabled_Exponent_Underflow):
4375           sign = EXTRACTED64(*frB, 0, 0);
4376           if (EXTRACTED64(*frB, 1, 11) == 0) {
4377             exp = -1022;
4378             frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4379           }
4380           if (EXTRACTED64(*frB, 1, 11) > 0) {
4381             exp = EXTRACTED64(*frB, 1, 11) - 1023;
4382             frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4383           }
4384             /* G|R|X == zero from above */
4385             while (exp < -126) {
4386               exp = exp + 1;
4387               frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4388                           | MASKED64(frac_grx, 55, 55));
4389             }
4390           FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4391           Round_Single(processor, sign, &exp, &frac_grx);
4392           FPSCR_SET_XX(FPSCR & fpscr_fi);
4393           if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4394             *frT = INSERTED64(sign, 0, 0);
4395             if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4396             if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4397           }
4398           if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4399             if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4400               if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4401               if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4402             }
4403             if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4404               if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4405               if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4406             }
4407             /*Normalize_Operand:*/
4408               while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4409                 exp = exp - 1;
4410                 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1,  52), 0, 51);
4411               }
4412             *frT = (INSERTED64(sign, 0, 0)
4413                     | INSERTED64(exp + 1023, 1, 11)
4414                     | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4415           }
4416           GOTO(Done);
4417         /**/
4418         LABEL(Enabled_Exponent_Underflow):
4419           FPSCR_SET_UX(1);
4420           sign = EXTRACTED64(*frB, 0, 0);
4421           if (EXTRACTED64(*frB, 1, 11) == 0) {
4422             exp = -1022;
4423             frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4424           }
4425           if (EXTRACTED64(*frB, 1, 11) > 0) {
4426             exp = EXTRACTED64(*frB, 1, 11) - 1023;
4427             frac_grx = (BIT64(0) |
4428                         INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4429           }
4430           /*Normalize_Operand:*/
4431             while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4432               exp = exp - 1;
4433               frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4434             }
4435           Round_Single(processor, sign, &exp, &frac_grx);
4436           FPSCR_SET_XX(FPSCR & fpscr_fi);
4437           exp = exp + 192;
4438           *frT = (INSERTED64(sign, 0, 0)
4439                   | INSERTED64(exp + 1023, 1, 11)
4440                   | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4441           if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4442           if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4443           GOTO(Done);
4444         /**/
4445         LABEL(Disabled_Exponent_Overflow):
4446           FPSCR_SET_OX(1);
4447           if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4448             if (EXTRACTED64(*frB, 0, 0) == 0) {
4449               *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4450               FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4451             }
4452             if (EXTRACTED64(*frB, 0, 0) == 1) {
4453               *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4454               FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4455             }
4456           }
4457           if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4458             if (EXTRACTED64(*frB, 0, 0) == 0) {
4459               *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4460               FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4461             }
4462             if (EXTRACTED64(*frB, 0, 0) == 1) {
4463               *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4464               FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4465             }
4466           }
4467           if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4468             if (EXTRACTED64(*frB, 0, 0) == 0) {
4469               *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4470               FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4471             }
4472             if (EXTRACTED64(*frB, 0, 0) == 1) {
4473               *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4474               FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4475             }
4476           }
4477           if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4478             if (EXTRACTED64(*frB, 0, 0) == 0) {
4479               *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4480               FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4481             }
4482             if (EXTRACTED64(*frB, 0, 0) == 1) {
4483               *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4484               FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4485             }
4486           }
4487           /* FPSCR[FR] <- undefined */
4488           FPSCR_SET_FI(1);
4489           FPSCR_SET_XX(1);
4490           GOTO(Done);
4491         /**/
4492         LABEL(Enabled_Exponent_Overflow):
4493           sign = EXTRACTED64(*frB, 0, 0);
4494           exp = EXTRACTED64(*frB, 1, 11) - 1023;
4495           frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4496           Round_Single(processor, sign, &exp, &frac_grx);
4497           FPSCR_SET_XX(FPSCR & fpscr_fi);
4498         /**/
4499         LABEL(Enabled_Overflow):
4500           FPSCR_SET_OX(1);
4501           exp = exp - 192;
4502           *frT = (INSERTED64(sign, 0, 0)
4503                   | INSERTED64(exp + 1023, 1, 11)
4504                   | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4505           if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4506           if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4507           GOTO(Done);
4508         /**/
4509         LABEL(Zero_Operand):
4510           *frT = *frB;
4511           if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4512           if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4513           FPSCR_SET_FR(0);
4514           FPSCR_SET_FI(0);
4515           GOTO(Done);
4516         /**/
4517         LABEL(Infinity_Operand):
4518           *frT = *frB;
4519           if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4520           if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4521           FPSCR_SET_FR(0);
4522           FPSCR_SET_FI(0);
4523           GOTO(Done);
4524         /**/
4525         LABEL(QNaN_Operand):
4526           *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4527           FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4528           FPSCR_SET_FR(0);
4529           FPSCR_SET_FI(0);
4530           GOTO(Done);
4531         /**/
4532         LABEL(SNaN_Operand):
4533           FPSCR_OR_VX(fpscr_vxsnan);
4534           if ((FPSCR & fpscr_ve) == 0) {
4535             *frT = (MASKED64(*frB, 0, 11)
4536                     | BIT64(12)
4537                     | MASKED64(*frB, 13, 34));
4538             FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4539           }
4540           FPSCR_SET_FR(0);
4541           FPSCR_SET_FI(0);
4542           GOTO(Done);
4543         /**/
4544         LABEL(Normal_Operand):
4545           sign = EXTRACTED64(*frB, 0, 0);
4546           exp = EXTRACTED64(*frB, 1, 11) - 1023;
4547           frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4548           Round_Single(processor, sign, &exp, &frac_grx);
4549           FPSCR_SET_XX(FPSCR & fpscr_fi);
4550           if (exp > 127 && (FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4551           if (exp > 127 && (FPSCR & fpscr_oe) != 0) GOTO(Enabled_Overflow);
4552           *frT = (INSERTED64(sign, 0, 0)
4553                   | INSERTED64(exp + 1023, 1, 11)
4554                   | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4555           if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4556           if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4557           GOTO(Done);
4558         /**/
4559         LABEL(Done):
4560           PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4561
4562
4563 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4564         floating_point_assist_interrupt(processor, cia);
4565
4566 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4567         floating_point_assist_interrupt(processor, cia);
4568
4569 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4570         floating_point_assist_interrupt(processor, cia);
4571
4572 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4573 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4574 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4575 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4576 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4577         FPSCR_BEGIN;
4578         convert_to_integer(processor, cia,
4579                            frT, *frB,
4580                            fpscr_rn_round_towards_zero, 32);
4581         FPSCR_END(Rc);
4582         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4583
4584 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4585         int sign = EXTRACTED64(*frB, 0, 0);
4586         int exp = 63;
4587         unsigned64 frac = *frB;
4588         /***/
4589           if (frac == 0) GOTO(Zero_Operand);
4590           if (sign == 1) frac = ~frac + 1;
4591           while (EXTRACTED64(frac, 0, 0) == 0) {
4592             /*??? do the loop 0 times if (FRB) = max negative integer */
4593             frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4594             exp = exp - 1;
4595           }
4596           Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4597           if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4598           if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4599           *frT = (INSERTED64(sign, 0, 0)
4600                   | INSERTED64(exp + 1023, 1, 11)
4601                   | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4602           GOTO(Done);
4603         /**/
4604         LABEL(Zero_Operand):
4605           FPSCR_SET_FR(0);
4606           FPSCR_SET_FI(0);
4607           FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4608           *frT = 0;
4609           GOTO(Done);
4610         /**/
4611         LABEL(Done):
4612           PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4613
4614
4615 #
4616 # I.4.6.7 Floating-Point Compare Instructions
4617 #
4618
4619 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4620 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4621 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4622 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4623 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4624         FPSCR_BEGIN;
4625         unsigned c;
4626         if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4627           c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4628         else if (is_less_than(frA, frB))
4629           c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4630         else if (is_greater_than(frA, frB))
4631           c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4632         else
4633           c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4634         FPSCR_SET_FPCC(c);
4635         CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4636         if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4637           FPSCR_OR_VX(fpscr_vxsnan);
4638         FPSCR_END(0);
4639         PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4640
4641 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4642 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4643 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4644 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4645 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4646         FPSCR_BEGIN;
4647         unsigned c;
4648         if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4649           c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4650         else if (is_less_than(frA, frB))
4651           c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4652         else if (is_greater_than(frA, frB))
4653           c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4654         else
4655           c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4656         FPSCR_SET_FPCC(c);
4657         CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4658         if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4659           FPSCR_OR_VX(fpscr_vxsnan);
4660           if ((FPSCR & fpscr_ve) == 0)
4661             FPSCR_OR_VX(fpscr_vxvc);
4662         }
4663         else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4664           FPSCR_OR_VX(fpscr_vxvc);
4665         }
4666         FPSCR_END(0);
4667         PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4668
4669
4670 #
4671 # I.4.6.8 Floating-Point Status and Control Register Instructions
4672 #
4673
4674 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4675         FPSCR_BEGIN;
4676         *frT = FPSCR;
4677         FPSCR_END(Rc);
4678
4679 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4680         FPSCR_BEGIN;
4681         unsigned field = FPSCR_FIELD(BFA);
4682         CR_SET(BF, field);
4683         FPSCR_SET(BFA, 0); /* FPSCR_END fixes up FEX/VX */
4684         FPSCR_END(0);
4685
4686 0.63,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4687         FPSCR_BEGIN;
4688         FPSCR_SET(BF, U);
4689         FPSCR_END(Rc);
4690
4691 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4692         FPSCR_BEGIN;
4693         int i;
4694         for (i = 0; i < 8; i++) {
4695           if ((FLM & BIT8(i))) {
4696             FPSCR &= ~MASK32(i*4, i*4+3);
4697             FPSCR |= MASKED32(*frB, i*4, i*4+3);
4698           }
4699         }
4700         FPSCR_END(Rc);
4701
4702 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4703         FPSCR_BEGIN;
4704         unsigned32 bit = BIT32(BT);
4705         FPSCR &= ~bit;
4706         FPSCR_END(Rc);
4707
4708 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4709         FPSCR_BEGIN;
4710         unsigned32 bit = BIT32(BT);
4711         if (bit & fpscr_fi)
4712           bit |= fpscr_xx;
4713         if ((bit & fpscr_vx_bits))
4714           bit |= fpscr_fx;
4715         /* note - omit vx bit */
4716         if ((bit & (fpscr_ox | fpscr_ux | fpscr_zx | fpscr_xx)))
4717           bit |= fpscr_fx;
4718         FPSCR |= bit;
4719         FPSCR_END(Rc);
4720
4721 #
4722 # I.A.1.2 Floating-Point Arithmetic Instructions
4723 #
4724
4725 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root
4726         program_interrupt(processor, cia, optional_instruction_program_interrupt);
4727
4728 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root Single
4729         program_interrupt(processor, cia, optional_instruction_program_interrupt);
4730
4731 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f,o::Floating Reciprocal Estimate Single
4732         program_interrupt(processor, cia, optional_instruction_program_interrupt);
4733
4734 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f,o::Floating Reciprocal Square Root Estimate
4735         program_interrupt(processor, cia, optional_instruction_program_interrupt);
4736
4737 #
4738 # I.A.1.3 Floating-Point Select Instruction
4739 #
4740
4741 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f,o::Floating Select
4742 *601: PPC_UNIT_BAD,   PPC_UNIT_BAD,   0,  0,  0
4743 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4744 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4745 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4746         if (CURRENT_MODEL == MODEL_ppc601) {
4747           program_interrupt(processor, cia, optional_instruction_program_interrupt);
4748         } else {
4749           unsigned64 zero = 0;
4750           FPSCR_BEGIN;
4751           if (is_NaN(*frA, 0) || is_less_than (frA, &zero)) *frT = *frB;
4752           else                                              *frT = *frC;
4753           FPSCR_END(Rc);
4754           PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4755         }
4756
4757 #
4758 # II.3.2 Cache Management Instructions
4759 #
4760
4761 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4762 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4763 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4764 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4765 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4766         /* blindly flush all instruction cache entries */
4767         #if WITH_IDECODE_CACHE_SIZE
4768         cpu_flush_icache(processor);
4769         #endif
4770         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4771
4772 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4773 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4774 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4775 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4776 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4777         cpu_synchronize_context(processor, cia);
4778         PPC_INSN_INT(0, 0, 0);
4779
4780
4781 #
4782 # II.3.2.2 Data Cache Instructions
4783 #
4784
4785 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4786 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4787 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4788 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4789 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4790         TRACE(trace_tbd,("Data Cache Block Touch\n"));
4791         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4792
4793 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4794 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4795 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4796 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4797 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4798         TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4799         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4800
4801 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4802 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4803 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   10, 10, 0
4804 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   10, 10, 0
4805 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4806         TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4807         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4808
4809 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4810 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4811 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4812 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4813 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4814         TRACE(trace_tbd,("Data Cache Block Store\n"));
4815         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4816
4817 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4818 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4819 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4820 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4821 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4822         TRACE(trace_tbd,("Data Cache Block Flush\n"));
4823         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4824
4825 #
4826 # II.3.3 Enforce In-order Execution of I/O Instruction
4827 #
4828
4829 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4830         /* Since this model has no instruction overlap
4831            this instruction need do nothing */
4832
4833 #
4834 # II.4.1 Time Base Instructions
4835 #
4836
4837 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4838 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4839 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4840 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
4841         int n = (tbr{5:9} << 5) | tbr{0:4};
4842         if (n == 268) {
4843           if (is_64bit_implementation) *rT = TB;
4844           else                         *rT = EXTRACTED64(TB, 32, 63);
4845         }
4846         else if (n == 269) {
4847           if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4848           else                         *rT = EXTRACTED64(TB, 0, 31);
4849         }
4850         else
4851           program_interrupt(processor, cia,
4852                             illegal_instruction_program_interrupt);
4853
4854
4855 #
4856 # III.2.3.1 System Linkage Instructions
4857 #
4858
4859 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4860 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4861 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4862 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4863 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
4864         if (IS_PROBLEM_STATE(processor)) {
4865           program_interrupt(processor, cia,
4866                             privileged_instruction_program_interrupt);
4867         }
4868         else {
4869           MSR = (MASKED(SRR1, 0, 32)
4870                  | MASKED(SRR1, 37, 41)
4871                  | MASKED(SRR1, 48, 63));
4872           NIA = MASKED(SRR0, 0, 61);
4873           cpu_synchronize_context(processor, cia);
4874           check_masked_interrupts(processor);
4875         }
4876
4877 #
4878 # III.3.4.1 Move to/from System Register Instructions
4879 #
4880
4881 #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4882 #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4883 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4884 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4885 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4886 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4887 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4888         if (IS_PROBLEM_STATE(processor))
4889           program_interrupt(processor, cia,
4890                             privileged_instruction_program_interrupt);
4891         else {
4892           MSR = *rS;
4893           check_masked_interrupts(processor);
4894         }
4895
4896 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4897 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4898 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4899 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4900 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
4901         if (IS_PROBLEM_STATE(processor))
4902           program_interrupt(processor, cia,
4903                             privileged_instruction_program_interrupt);
4904         else {
4905           *rT = MSR;
4906           check_masked_interrupts(processor);
4907         }
4908
4909
4910 #
4911 # III.4.11.1 Cache Management Instructions
4912 #
4913
4914 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4915 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4916 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4917 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4918 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4919         if (IS_PROBLEM_STATE(processor))
4920           program_interrupt(processor, cia,
4921                             privileged_instruction_program_interrupt);
4922         else
4923           TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4924
4925 #
4926 # III.4.11.2 Segment Register Manipulation Instructions
4927 #
4928
4929 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4930 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4931 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4932 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4933 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4934         if (IS_PROBLEM_STATE(processor))
4935           program_interrupt(processor, cia,
4936                             privileged_instruction_program_interrupt);
4937         else
4938           SEGREG(SR) = *rS;
4939
4940 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4941 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4942 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4943 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4944 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4945         if (IS_PROBLEM_STATE(processor))
4946           program_interrupt(processor, cia,
4947                             privileged_instruction_program_interrupt);
4948         else
4949           SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4950
4951 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4952 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
4953 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4954 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4955 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4956         if (IS_PROBLEM_STATE(processor))
4957           program_interrupt(processor, cia,
4958                             privileged_instruction_program_interrupt);
4959         else
4960           *rT = SEGREG(SR);
4961
4962 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4963 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
4964 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4965 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4966 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4967         if (IS_PROBLEM_STATE(processor))
4968           program_interrupt(processor, cia,
4969                             privileged_instruction_program_interrupt);
4970         else
4971           *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4972
4973
4974 #
4975 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4976 #
4977
4978 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4979
4980 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4981
4982 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4983         if (IS_PROBLEM_STATE(processor))
4984           program_interrupt(processor, cia,
4985                             privileged_instruction_program_interrupt);
4986         else {
4987           int nr = 0;
4988           cpu *proc;
4989           while (1) {
4990             proc = psim_cpu(cpu_system(processor), nr);
4991             if (proc == NULL) break;
4992             cpu_page_tlb_invalidate_entry(proc, *rB);
4993             nr++;
4994           }
4995         }
4996
4997 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4998         if (IS_PROBLEM_STATE(processor))
4999           program_interrupt(processor, cia,
5000                             privileged_instruction_program_interrupt);
5001         else {
5002           int nr = 0;
5003           cpu *proc;
5004           while (1) {
5005             proc = psim_cpu(cpu_system(processor), nr);
5006             if (proc == NULL) break;
5007             cpu_page_tlb_invalidate_all(proc);
5008             nr++;
5009           }
5010         }
5011
5012 0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
5013         /* nothing happens here - always in sync */
5014
5015 #
5016 # III.A.1.2 External Access Instructions
5017 #
5018
5019 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
5020
5021 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
5022
5023 :include:::altivec.igen
5024 :include:::e500.igen