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