d76a7654c50db0013e98081fe6f8dfe7708e0e0b
[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.3.3.15 Fixed-Point Select
3459 #
3460
3461 0.31,6.RT,11.RA,16.RB,21.BF,26.15,31./:A::isel:Integer Select
3462         unsigned_word a;
3463         if (RA_is_0) a = 0;
3464         else         a = *rA;
3465         if (CR & (1 << (31 - BF)))
3466           *rT = a;
3467         else
3468           *rT = *rB;
3469
3470 #
3471 # I.4.6.2 Floating-Point Load Instructions
3472 #
3473
3474 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
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 + EXTS(D);
3484         *frT = DOUBLE(MEM(unsigned, EA, 4));
3485         PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3486
3487 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
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 b;
3493         unsigned_word EA;
3494         if (RA_is_0) b = 0;
3495         else         b = *rA;
3496         EA = b + *rB;
3497         *frT = DOUBLE(MEM(unsigned, EA, 4));
3498         PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3499
3500 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3501 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3502 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3503 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3504 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3505         unsigned_word EA;
3506         if (RA_is_0)
3507           program_interrupt(processor, cia,
3508                             illegal_instruction_program_interrupt);
3509         EA = *rA + EXTS(D);
3510         *frT = DOUBLE(MEM(unsigned, EA, 4));
3511         *rA = EA;
3512         PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3513
3514 0.31,6.FRT,11.RA,16.RB,21.567,31./:X:f::Load Floating-Point Single with Update Indexed
3515 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3516 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3517 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3518 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3519         unsigned_word EA;
3520         if (RA_is_0)
3521           program_interrupt(processor, cia,
3522                             illegal_instruction_program_interrupt);
3523         EA = *rA + *rB;
3524         *frT = DOUBLE(MEM(unsigned, EA, 4));
3525         *rA = EA;
3526         PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3527
3528 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
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 + EXTS(D);
3538         *frT = MEM(unsigned, EA, 8);
3539         PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3540
3541 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
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 b;
3547         unsigned_word EA;
3548         if (RA_is_0) b = 0;
3549         else         b = *rA;
3550         EA = b + *rB;
3551         *frT = MEM(unsigned, EA, 8);
3552         PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3553
3554 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3555 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3556 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3557 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3558 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3559         unsigned_word EA;
3560         if (RA_is_0)
3561           program_interrupt(processor, cia,
3562                             illegal_instruction_program_interrupt);
3563         EA = *rA + EXTS(D);
3564         *frT = MEM(unsigned, EA, 8);
3565         *rA = EA;
3566         PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3567
3568 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3569 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    3,  3,  0
3570 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3571 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3572 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3573         unsigned_word EA;
3574         if (RA_is_0)
3575           program_interrupt(processor, cia,
3576                             illegal_instruction_program_interrupt);
3577         EA = *rA + *rB;
3578         *frT = MEM(unsigned, EA, 8);
3579         *rA = EA;
3580         PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3581
3582
3583 #
3584 # I.4.6.3 Floating-Point Store Instructions
3585 #
3586
3587 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
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 + EXTS(D);
3597         STORE(EA, 4, SINGLE(*frS));
3598         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3599
3600 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
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 b;
3606         unsigned_word EA;
3607         if (RA_is_0) b = 0;
3608         else         b = *rA;
3609         EA = b + *rB;
3610         STORE(EA, 4, SINGLE(*frS));
3611         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3612
3613 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3614 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3615 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3616 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3617 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3618         unsigned_word EA;
3619         if (RA_is_0)
3620           program_interrupt(processor, cia,
3621                             illegal_instruction_program_interrupt);
3622         EA = *rA + EXTS(D);
3623         STORE(EA, 4, SINGLE(*frS));
3624         *rA = EA;
3625         PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3626
3627 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3628 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3629 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3630 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3631 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3632         unsigned_word EA;
3633         if (RA_is_0)
3634           program_interrupt(processor, cia,
3635                             illegal_instruction_program_interrupt);
3636         EA = *rA + *rB;
3637         STORE(EA, 4, SINGLE(*frS));
3638         *rA = EA;
3639         PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3640
3641 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
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 + EXTS(D);
3651         STORE(EA, 8, *frS);
3652         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3653
3654 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3655 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3656 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3657 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3658 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3659         unsigned_word b;
3660         unsigned_word EA;
3661         if (RA_is_0) b = 0;
3662         else         b = *rA;
3663         EA = b + *rB;
3664         STORE(EA, 8, *frS);
3665         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3666
3667 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point Integer Word Indexed
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 b;
3672         unsigned_word EA;
3673         if (RA_is_0) b = 0;
3674         else         b = *rA;
3675         EA = b + *rB;
3676         STORE(EA, 4, *frS);
3677         PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3678
3679 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3680 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3681 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3682 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3683 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3684         unsigned_word EA;
3685         if (RA_is_0)
3686           program_interrupt(processor, cia,
3687                             illegal_instruction_program_interrupt);
3688         EA = *rA + EXTS(D);
3689         STORE(EA, 8, *frS);
3690         *rA = EA;
3691         PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3692
3693 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3694 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3695 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3696 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3697 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3698         unsigned_word EA;
3699         if (RA_is_0)
3700           program_interrupt(processor, cia,
3701                             illegal_instruction_program_interrupt);
3702         EA = *rA + *rB;
3703         STORE(EA, 8, *frS);
3704         *rA = EA;
3705         PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3706
3707
3708 #
3709 # I.4.6.4 Floating-Point Move Instructions
3710 #
3711
3712 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3713 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3714 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3715 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3716 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3717         *frT = *frB;
3718         CR1_UPDATE(Rc);
3719         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3720
3721 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3722 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3723 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3724 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3725 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3726         *frT = *frB ^ BIT64(0);
3727         CR1_UPDATE(Rc);
3728         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3729
3730 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3731 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3732 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3733 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3734 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3735         *frT = *frB & ~BIT64(0);
3736         CR1_UPDATE(Rc);
3737         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3738
3739 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3740 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3741 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3742 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3743 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3744         *frT = *frB | BIT64(0);
3745         CR1_UPDATE(Rc);
3746         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3747
3748
3749 #
3750 # I.4.6.5 Floating-Point Arithmetic Instructions
3751 #
3752
3753 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3754 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3755 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3756 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3757 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3758         FPSCR_BEGIN;
3759         if (is_invalid_operation(processor, cia,
3760                                  *frA, *frB,
3761                                  fpscr_vxsnan | fpscr_vxisi,
3762                                  0, /*single?*/
3763                                  0) /*negate?*/) {
3764           invalid_arithemetic_operation(processor, cia,
3765                                         frT, *frA, *frB, 0,
3766                                         0, /*instruction_is_frsp*/
3767                                         0, /*instruction_is_convert_to_64bit*/
3768                                         0, /*instruction_is_convert_to_32bit*/
3769                                         0); /*single-precision*/
3770         }
3771         else {
3772           /*HACK!*/
3773           double s = *(double*)frA + *(double*)frB;
3774           *(double*)frT = s;
3775         }
3776         FPSCR_END(Rc);
3777         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3778
3779 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3780 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3781 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3782 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3783 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3784         FPSCR_BEGIN;
3785         if (is_invalid_operation(processor, cia,
3786                                  *frA, *frB,
3787                                  fpscr_vxsnan | fpscr_vxisi,
3788                                  1, /*single?*/
3789                                  0) /*negate?*/) {
3790           invalid_arithemetic_operation(processor, cia,
3791                                         frT, *frA, *frB, 0,
3792                                         0, /*instruction_is_frsp*/
3793                                         0, /*instruction_is_convert_to_64bit*/
3794                                         0, /*instruction_is_convert_to_32bit*/
3795                                         1); /*single-precision*/
3796         }
3797         else {
3798           /*HACK!*/
3799           float s = *(double*)frA + *(double*)frB;
3800           *(double*)frT = s;
3801         }
3802         FPSCR_END(Rc);
3803         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3804
3805 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3806 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3807 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3808 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3809 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3810         FPSCR_BEGIN;
3811         if (is_invalid_operation(processor, cia,
3812                                  *frA, *frB,
3813                                  fpscr_vxsnan | fpscr_vxisi,
3814                                  0, /*single?*/
3815                                  1) /*negate?*/) {
3816           invalid_arithemetic_operation(processor, cia,
3817                                         frT, *frA, *frB, 0,
3818                                         0, /*instruction_is_frsp*/
3819                                         0, /*instruction_is_convert_to_64bit*/
3820                                         0, /*instruction_is_convert_to_32bit*/
3821                                         0); /*single-precision*/
3822         }
3823         else {
3824           /*HACK!*/
3825           double s = *(double*)frA - *(double*)frB;
3826           *(double*)frT = s;
3827         }
3828         FPSCR_END(Rc);
3829         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3830
3831 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3832 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3833 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3834 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3835 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3836         FPSCR_BEGIN;
3837         if (is_invalid_operation(processor, cia,
3838                                  *frA, *frB,
3839                                  fpscr_vxsnan | fpscr_vxisi,
3840                                  1, /*single?*/
3841                                  1) /*negate?*/) {
3842           invalid_arithemetic_operation(processor, cia,
3843                                         frT, *frA, *frB, 0,
3844                                         0, /*instruction_is_frsp*/
3845                                         0, /*instruction_is_convert_to_64bit*/
3846                                         0, /*instruction_is_convert_to_32bit*/
3847                                         1); /*single-precision*/
3848         }
3849         else {
3850           /*HACK!*/
3851           float s = *(double*)frA - *(double*)frB;
3852           *(double*)frT = s;
3853         }
3854         FPSCR_END(Rc);
3855         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3856
3857 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3858 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
3859 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3860 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3861 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3862         FPSCR_BEGIN;
3863         if (is_invalid_operation(processor, cia,
3864                                  *frA, *frC,
3865                                  fpscr_vxsnan | fpscr_vximz,
3866                                  0, /*single?*/
3867                                  0) /*negate?*/) {
3868           invalid_arithemetic_operation(processor, cia,
3869                                         frT, *frA, 0, *frC,
3870                                         0, /*instruction_is_frsp*/
3871                                         0, /*instruction_is_convert_to_64bit*/
3872                                         0, /*instruction_is_convert_to_32bit*/
3873                                         0); /*single-precision*/
3874         }
3875         else {
3876           /*HACK!*/
3877           double s = *(double*)frA * *(double*)frC;
3878           *(double*)frT = s;
3879         }
3880         FPSCR_END(Rc);
3881         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3882
3883 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3884 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3885 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3886 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3887 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3888         FPSCR_BEGIN;
3889         if (is_invalid_operation(processor, cia,
3890                                  *frA, *frC,
3891                                  fpscr_vxsnan | fpscr_vximz,
3892                                  1, /*single?*/
3893                                  0) /*negate?*/) {
3894           invalid_arithemetic_operation(processor, cia,
3895                                         frT, *frA, 0, *frC,
3896                                         0, /*instruction_is_frsp*/
3897                                         0, /*instruction_is_convert_to_64bit*/
3898                                         0, /*instruction_is_convert_to_32bit*/
3899                                         1); /*single-precision*/
3900         }
3901         else {
3902           /*HACK!*/
3903           float s = *(double*)frA * *(double*)frC;
3904           *(double*)frT = s;
3905         }
3906         FPSCR_END(Rc);
3907         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3908
3909 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3910 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   31, 31, 0
3911 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   33, 33, 0
3912 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   33, 33, 0
3913 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   32, 32, 0
3914         FPSCR_BEGIN;
3915         if (is_invalid_operation(processor, cia,
3916                                  *frA, *frB,
3917                                  fpscr_vxsnan | fpscr_vxzdz,
3918                                  0, /*single?*/
3919                                  0) /*negate?*/) {
3920           invalid_arithemetic_operation(processor, cia,
3921                                         frT, *frA, *frB, 0,
3922                                         0, /*instruction_is_frsp*/
3923                                         0, /*instruction_is_convert_to_64bit*/
3924                                         0, /*instruction_is_convert_to_32bit*/
3925                                         0); /*single-precision*/
3926         }
3927         else if (is_invalid_zero_divide (processor, cia,
3928                                          *frA, *frB,
3929                                          0 /*single?*/)) {
3930           invalid_zero_divide_operation (processor, cia,
3931                                          frT, *frA, *frB,
3932                                          0 /*single?*/);
3933         }
3934         else {
3935           /*HACK!*/
3936           double s = *(double*)frA / *(double*)frB;
3937           *(double*)frT = s;
3938         }
3939         FPSCR_END(Rc);
3940         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3941
3942 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3943 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   17, 17, 0
3944 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
3945 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
3946 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
3947         FPSCR_BEGIN;
3948         if (is_invalid_operation(processor, cia,
3949                                  *frA, *frB,
3950                                  fpscr_vxsnan | fpscr_vxzdz,
3951                                  1, /*single?*/
3952                                  0) /*negate?*/) {
3953           invalid_arithemetic_operation(processor, cia,
3954                                         frT, *frA, *frB, 0,
3955                                         0, /*instruction_is_frsp*/
3956                                         0, /*instruction_is_convert_to_64bit*/
3957                                         0, /*instruction_is_convert_to_32bit*/
3958                                         1); /*single-precision*/
3959         }
3960         else if (is_invalid_zero_divide (processor, cia,
3961                                          *frA, *frB,
3962                                          1 /*single?*/)) {
3963           invalid_zero_divide_operation (processor, cia,
3964                                          frT, *frA, *frB,
3965                                          1 /*single?*/);
3966         }
3967         else {
3968           /*HACK!*/
3969           float s = *(double*)frA / *(double*)frB;
3970           *(double*)frT = s;
3971         }
3972         FPSCR_END(Rc);
3973         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3974
3975 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3976 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
3977 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3978 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3979 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3980         FPSCR_BEGIN;
3981         double product; /*HACK! - incorrectly loosing precision ... */
3982         /* compute the multiply */
3983         if (is_invalid_operation(processor, cia,
3984                                  *frA, *frC,
3985                                  fpscr_vxsnan | fpscr_vximz,
3986                                  0, /*single?*/
3987                                  0) /*negate?*/) {
3988           union { double d; unsigned64 u; } tmp;
3989           invalid_arithemetic_operation(processor, cia,
3990                                         &tmp.u, *frA, 0, *frC,
3991                                         0, /*instruction_is_frsp*/
3992                                         0, /*instruction_is_convert_to_64bit*/
3993                                         0, /*instruction_is_convert_to_32bit*/
3994                                         0); /*single-precision*/
3995           product = tmp.d;
3996         }
3997         else {
3998           /*HACK!*/
3999           product = *(double*)frA * *(double*)frC;
4000         }
4001         /* compute the add */
4002         if (is_invalid_operation(processor, cia,
4003                                  product, *frB,
4004                                  fpscr_vxsnan | fpscr_vxisi,
4005                                  0, /*single?*/
4006                                  0) /*negate?*/) {
4007           invalid_arithemetic_operation(processor, cia,
4008                                         frT, product, *frB, 0,
4009                                         0, /*instruction_is_frsp*/
4010                                         0, /*instruction_is_convert_to_64bit*/
4011                                         0, /*instruction_is_convert_to_32bit*/
4012                                         0); /*single-precision*/
4013         }
4014         else {
4015           /*HACK!*/
4016           double s = product + *(double*)frB;
4017           *(double*)frT = s;
4018         }
4019         FPSCR_END(Rc);
4020         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4021
4022 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
4023 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4024 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4025 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4026 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4027         FPSCR_BEGIN;
4028         float product; /*HACK! - incorrectly loosing precision ... */
4029         /* compute the multiply */
4030         if (is_invalid_operation(processor, cia,
4031                                  *frA, *frC,
4032                                  fpscr_vxsnan | fpscr_vximz,
4033                                  1, /*single?*/
4034                                  0) /*negate?*/) {
4035           union { double d; unsigned64 u; } tmp;
4036           invalid_arithemetic_operation(processor, cia,
4037                                         &tmp.u, *frA, 0, *frC,
4038                                         0, /*instruction_is_frsp*/
4039                                         0, /*instruction_is_convert_to_64bit*/
4040                                         0, /*instruction_is_convert_to_32bit*/
4041                                         0); /*single-precision*/
4042           product = tmp.d;
4043         }
4044         else {
4045           /*HACK!*/
4046           product = *(double*)frA * *(double*)frC;
4047         }
4048         /* compute the add */
4049         if (is_invalid_operation(processor, cia,
4050                                  product, *frB,
4051                                  fpscr_vxsnan | fpscr_vxisi,
4052                                  1, /*single?*/
4053                                  0) /*negate?*/) {
4054           invalid_arithemetic_operation(processor, cia,
4055                                         frT, product, *frB, 0,
4056                                         0, /*instruction_is_frsp*/
4057                                         0, /*instruction_is_convert_to_64bit*/
4058                                         0, /*instruction_is_convert_to_32bit*/
4059                                         0); /*single-precision*/
4060         }
4061         else {
4062           /*HACK!*/
4063           float s = product + *(double*)frB;
4064           *(double*)frT = (double)s;
4065         }
4066         FPSCR_END(Rc);
4067         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4068
4069 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
4070 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
4071 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4072 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4073 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4074         FPSCR_BEGIN;
4075         double product; /*HACK! - incorrectly loosing precision ... */
4076         /* compute the multiply */
4077         if (is_invalid_operation(processor, cia,
4078                                  *frA, *frC,
4079                                  fpscr_vxsnan | fpscr_vximz,
4080                                  0, /*single?*/
4081                                  0) /*negate?*/) {
4082           union { double d; unsigned64 u; } tmp;
4083           invalid_arithemetic_operation(processor, cia,
4084                                         &tmp.u, *frA, 0, *frC,
4085                                         0, /*instruction_is_frsp*/
4086                                         0, /*instruction_is_convert_to_64bit*/
4087                                         0, /*instruction_is_convert_to_32bit*/
4088                                         0); /*single-precision*/
4089           product = tmp.d;
4090         }
4091         else {
4092           /*HACK!*/
4093           product = *(double*)frA * *(double*)frC;
4094         }
4095         /* compute the subtract */
4096         if (is_invalid_operation(processor, cia,
4097                                  product, *frB,
4098                                  fpscr_vxsnan | fpscr_vxisi,
4099                                  0, /*single?*/
4100                                  0) /*negate?*/) {
4101           invalid_arithemetic_operation(processor, cia,
4102                                         frT, product, *frB, 0,
4103                                         0, /*instruction_is_frsp*/
4104                                         0, /*instruction_is_convert_to_64bit*/
4105                                         0, /*instruction_is_convert_to_32bit*/
4106                                         0); /*single-precision*/
4107         }
4108         else {
4109           /*HACK!*/
4110           double s = product - *(double*)frB;
4111           *(double*)frT = s;
4112         }
4113         FPSCR_END(Rc);
4114         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4115
4116 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
4117 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4118 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4119 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4120 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4121         FPSCR_BEGIN;
4122         float product; /*HACK! - incorrectly loosing precision ... */
4123         /* compute the multiply */
4124         if (is_invalid_operation(processor, cia,
4125                                  *frA, *frC,
4126                                  fpscr_vxsnan | fpscr_vximz,
4127                                  1, /*single?*/
4128                                  0) /*negate?*/) {
4129           union { double d; unsigned64 u; } tmp;
4130           invalid_arithemetic_operation(processor, cia,
4131                                         &tmp.u, *frA, 0, *frC,
4132                                         0, /*instruction_is_frsp*/
4133                                         0, /*instruction_is_convert_to_64bit*/
4134                                         0, /*instruction_is_convert_to_32bit*/
4135                                         0); /*single-precision*/
4136           product = tmp.d;
4137         }
4138         else {
4139           /*HACK!*/
4140           product = *(double*)frA * *(double*)frC;
4141         }
4142         /* compute the subtract */
4143         if (is_invalid_operation(processor, cia,
4144                                  product, *frB,
4145                                  fpscr_vxsnan | fpscr_vxisi,
4146                                  1, /*single?*/
4147                                  0) /*negate?*/) {
4148           invalid_arithemetic_operation(processor, cia,
4149                                         frT, product, *frB, 0,
4150                                         0, /*instruction_is_frsp*/
4151                                         0, /*instruction_is_convert_to_64bit*/
4152                                         0, /*instruction_is_convert_to_32bit*/
4153                                         0); /*single-precision*/
4154         }
4155         else {
4156           /*HACK!*/
4157           float s = product - *(double*)frB;
4158           *(double*)frT = (double)s;
4159         }
4160         FPSCR_END(Rc);
4161         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4162
4163 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
4164 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
4165 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4166 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4167 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4168         FPSCR_BEGIN;
4169         double product; /*HACK! - incorrectly loosing precision ... */
4170         /* compute the multiply */
4171         if (is_invalid_operation(processor, cia,
4172                                  *frA, *frC,
4173                                  fpscr_vxsnan | fpscr_vximz,
4174                                  0, /*single?*/
4175                                  0) /*negate?*/) {
4176           union { double d; unsigned64 u; } tmp;
4177           invalid_arithemetic_operation(processor, cia,
4178                                         &tmp.u, *frA, 0, *frC,
4179                                         0, /*instruction_is_frsp*/
4180                                         0, /*instruction_is_convert_to_64bit*/
4181                                         0, /*instruction_is_convert_to_32bit*/
4182                                         0); /*single-precision*/
4183           product = tmp.d;
4184         }
4185         else {
4186           /*HACK!*/
4187           product = *(double*)frA * *(double*)frC;
4188         }
4189         /* compute the add */
4190         if (is_invalid_operation(processor, cia,
4191                                  product, *frB,
4192                                  fpscr_vxsnan | fpscr_vxisi,
4193                                  0, /*single?*/
4194                                  0) /*negate?*/) {
4195           invalid_arithemetic_operation(processor, cia,
4196                                         frT, product, *frB, 0,
4197                                         0, /*instruction_is_frsp*/
4198                                         0, /*instruction_is_convert_to_64bit*/
4199                                         0, /*instruction_is_convert_to_32bit*/
4200                                         0); /*single-precision*/
4201         }
4202         else {
4203           /*HACK!*/
4204           double s = -(product + *(double*)frB);
4205           *(double*)frT = s;
4206         }
4207         FPSCR_END(Rc);
4208         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4209
4210 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
4211 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4212 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4213 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4214 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4215         FPSCR_BEGIN;
4216         float product; /*HACK! - incorrectly loosing precision ... */
4217         /* compute the multiply */
4218         if (is_invalid_operation(processor, cia,
4219                                  *frA, *frC,
4220                                  fpscr_vxsnan | fpscr_vximz,
4221                                  1, /*single?*/
4222                                  0) /*negate?*/) {
4223           union { double d; unsigned64 u; } tmp;
4224           invalid_arithemetic_operation(processor, cia,
4225                                         &tmp.u, *frA, 0, *frC,
4226                                         0, /*instruction_is_frsp*/
4227                                         0, /*instruction_is_convert_to_64bit*/
4228                                         0, /*instruction_is_convert_to_32bit*/
4229                                         0); /*single-precision*/
4230           product = tmp.d;
4231         }
4232         else {
4233           /*HACK!*/
4234           product = *(double*)frA * *(double*)frC;
4235         }
4236         /* compute the add */
4237         if (is_invalid_operation(processor, cia,
4238                                  product, *frB,
4239                                  fpscr_vxsnan | fpscr_vxisi,
4240                                  1, /*single?*/
4241                                  0) /*negate?*/) {
4242           invalid_arithemetic_operation(processor, cia,
4243                                         frT, product, *frB, 0,
4244                                         0, /*instruction_is_frsp*/
4245                                         0, /*instruction_is_convert_to_64bit*/
4246                                         0, /*instruction_is_convert_to_32bit*/
4247                                         0); /*single-precision*/
4248         }
4249         else {
4250           /*HACK!*/
4251           float s = -(product + *(double*)frB);
4252           *(double*)frT = (double)s;
4253         }
4254         FPSCR_END(Rc);
4255         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4256
4257 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
4258 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
4259 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4260 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4261 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4262         FPSCR_BEGIN;
4263         double product; /*HACK! - incorrectly loosing precision ... */
4264         /* compute the multiply */
4265         if (is_invalid_operation(processor, cia,
4266                                  *frA, *frC,
4267                                  fpscr_vxsnan | fpscr_vximz,
4268                                  0, /*single?*/
4269                                  0) /*negate?*/) {
4270           union { double d; unsigned64 u; } tmp;
4271           invalid_arithemetic_operation(processor, cia,
4272                                         &tmp.u, *frA, 0, *frC,
4273                                         0, /*instruction_is_frsp*/
4274                                         0, /*instruction_is_convert_to_64bit*/
4275                                         0, /*instruction_is_convert_to_32bit*/
4276                                         0); /*single-precision*/
4277           product = tmp.d;
4278         }
4279         else {
4280           /*HACK!*/
4281           product = *(double*)frA * *(double*)frC;
4282         }
4283         /* compute the subtract */
4284         if (is_invalid_operation(processor, cia,
4285                                  product, *frB,
4286                                  fpscr_vxsnan | fpscr_vxisi,
4287                                  0, /*single?*/
4288                                  0) /*negate?*/) {
4289           invalid_arithemetic_operation(processor, cia,
4290                                         frT, product, *frB, 0,
4291                                         0, /*instruction_is_frsp*/
4292                                         0, /*instruction_is_convert_to_64bit*/
4293                                         0, /*instruction_is_convert_to_32bit*/
4294                                         0); /*single-precision*/
4295         }
4296         else {
4297           /*HACK!*/
4298           double s = -(product - *(double*)frB);
4299           *(double*)frT = s;
4300         }
4301         FPSCR_END(Rc);
4302         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4303
4304 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
4305 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4306 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4307 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4308 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4309         FPSCR_BEGIN;
4310         float product; /*HACK! - incorrectly loosing precision ... */
4311         /* compute the multiply */
4312         if (is_invalid_operation(processor, cia,
4313                                  *frA, *frC,
4314                                  fpscr_vxsnan | fpscr_vximz,
4315                                  1, /*single?*/
4316                                  0) /*negate?*/) {
4317           union { double d; unsigned64 u; } tmp;
4318           invalid_arithemetic_operation(processor, cia,
4319                                         &tmp.u, *frA, 0, *frC,
4320                                         0, /*instruction_is_frsp*/
4321                                         0, /*instruction_is_convert_to_64bit*/
4322                                         0, /*instruction_is_convert_to_32bit*/
4323                                         0); /*single-precision*/
4324           product = tmp.d;
4325         }
4326         else {
4327           /*HACK!*/
4328           product = *(double*)frA * *(double*)frC;
4329         }
4330         /* compute the subtract */
4331         if (is_invalid_operation(processor, cia,
4332                                  product, *frB,
4333                                  fpscr_vxsnan | fpscr_vxisi,
4334                                  1, /*single?*/
4335                                  0) /*negate?*/) {
4336           invalid_arithemetic_operation(processor, cia,
4337                                         frT, product, *frB, 0,
4338                                         0, /*instruction_is_frsp*/
4339                                         0, /*instruction_is_convert_to_64bit*/
4340                                         0, /*instruction_is_convert_to_32bit*/
4341                                         0); /*single-precision*/
4342         }
4343         else {
4344           /*HACK!*/
4345           float s = -(product - *(double*)frB);
4346           *(double*)frT = (double)s;
4347         }
4348         FPSCR_END(Rc);
4349         PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4350
4351
4352 #
4353 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4354 #
4355
4356 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4357 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4358 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4359 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4360 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4361         int sign;
4362         int exp;
4363         unsigned64 frac_grx;
4364         /***/
4365           /* split off cases for what to do */
4366           if (EXTRACTED64(*frB, 1, 11) < 897
4367               && EXTRACTED64(*frB, 1, 63) > 0) {
4368               if ((FPSCR & fpscr_ue) == 0) GOTO(Disabled_Exponent_Underflow);
4369               if ((FPSCR & fpscr_ue) != 0) GOTO(Enabled_Exponent_Underflow);
4370           }
4371           if (EXTRACTED64(*frB, 1, 11) > 1150
4372               && EXTRACTED64(*frB, 1, 11) < 2047) {
4373               if ((FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4374               if ((FPSCR & fpscr_oe) != 0) GOTO(Enabled_Exponent_Overflow);
4375           }
4376           if (EXTRACTED64(*frB, 1, 11) > 896
4377               && EXTRACTED64(*frB, 1, 11) < 1151) GOTO(Normal_Operand);
4378           if (EXTRACTED64(*frB, 1, 63) == 0) GOTO(Zero_Operand);
4379           if (EXTRACTED64(*frB, 1, 11) == 2047) {
4380             if (EXTRACTED64(*frB, 12, 63) == 0) GOTO(Infinity_Operand);
4381             if (EXTRACTED64(*frB, 12, 12) == 1) GOTO(QNaN_Operand);
4382             if (EXTRACTED64(*frB, 12, 12) == 0
4383                 && EXTRACTED64(*frB, 13, 63) > 0) GOTO(SNaN_Operand);
4384           }
4385         /**/
4386         LABEL(Disabled_Exponent_Underflow):
4387           sign = EXTRACTED64(*frB, 0, 0);
4388           if (EXTRACTED64(*frB, 1, 11) == 0) {
4389             exp = -1022;
4390             frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4391           }
4392           if (EXTRACTED64(*frB, 1, 11) > 0) {
4393             exp = EXTRACTED64(*frB, 1, 11) - 1023;
4394             frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4395           }
4396             /* G|R|X == zero from above */
4397             while (exp < -126) {
4398               exp = exp + 1;
4399               frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4400                           | MASKED64(frac_grx, 55, 55));
4401             }
4402           FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4403           Round_Single(processor, sign, &exp, &frac_grx);
4404           FPSCR_SET_XX(FPSCR & fpscr_fi);
4405           if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4406             *frT = INSERTED64(sign, 0, 0);
4407             if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4408             if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4409           }
4410           if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4411             if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4412               if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4413               if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4414             }
4415             if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4416               if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4417               if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4418             }
4419             /*Normalize_Operand:*/
4420               while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4421                 exp = exp - 1;
4422                 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1,  52), 0, 51);
4423               }
4424             *frT = (INSERTED64(sign, 0, 0)
4425                     | INSERTED64(exp + 1023, 1, 11)
4426                     | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4427           }
4428           GOTO(Done);
4429         /**/
4430         LABEL(Enabled_Exponent_Underflow):
4431           FPSCR_SET_UX(1);
4432           sign = EXTRACTED64(*frB, 0, 0);
4433           if (EXTRACTED64(*frB, 1, 11) == 0) {
4434             exp = -1022;
4435             frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4436           }
4437           if (EXTRACTED64(*frB, 1, 11) > 0) {
4438             exp = EXTRACTED64(*frB, 1, 11) - 1023;
4439             frac_grx = (BIT64(0) |
4440                         INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4441           }
4442           /*Normalize_Operand:*/
4443             while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4444               exp = exp - 1;
4445               frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4446             }
4447           Round_Single(processor, sign, &exp, &frac_grx);
4448           FPSCR_SET_XX(FPSCR & fpscr_fi);
4449           exp = exp + 192;
4450           *frT = (INSERTED64(sign, 0, 0)
4451                   | INSERTED64(exp + 1023, 1, 11)
4452                   | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4453           if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4454           if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4455           GOTO(Done);
4456         /**/
4457         LABEL(Disabled_Exponent_Overflow):
4458           FPSCR_SET_OX(1);
4459           if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4460             if (EXTRACTED64(*frB, 0, 0) == 0) {
4461               *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4462               FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4463             }
4464             if (EXTRACTED64(*frB, 0, 0) == 1) {
4465               *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4466               FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4467             }
4468           }
4469           if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4470             if (EXTRACTED64(*frB, 0, 0) == 0) {
4471               *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4472               FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4473             }
4474             if (EXTRACTED64(*frB, 0, 0) == 1) {
4475               *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4476               FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4477             }
4478           }
4479           if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4480             if (EXTRACTED64(*frB, 0, 0) == 0) {
4481               *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4482               FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4483             }
4484             if (EXTRACTED64(*frB, 0, 0) == 1) {
4485               *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4486               FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4487             }
4488           }
4489           if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4490             if (EXTRACTED64(*frB, 0, 0) == 0) {
4491               *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4492               FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4493             }
4494             if (EXTRACTED64(*frB, 0, 0) == 1) {
4495               *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4496               FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4497             }
4498           }
4499           /* FPSCR[FR] <- undefined */
4500           FPSCR_SET_FI(1);
4501           FPSCR_SET_XX(1);
4502           GOTO(Done);
4503         /**/
4504         LABEL(Enabled_Exponent_Overflow):
4505           sign = EXTRACTED64(*frB, 0, 0);
4506           exp = EXTRACTED64(*frB, 1, 11) - 1023;
4507           frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4508           Round_Single(processor, sign, &exp, &frac_grx);
4509           FPSCR_SET_XX(FPSCR & fpscr_fi);
4510         /**/
4511         LABEL(Enabled_Overflow):
4512           FPSCR_SET_OX(1);
4513           exp = exp - 192;
4514           *frT = (INSERTED64(sign, 0, 0)
4515                   | INSERTED64(exp + 1023, 1, 11)
4516                   | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4517           if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4518           if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4519           GOTO(Done);
4520         /**/
4521         LABEL(Zero_Operand):
4522           *frT = *frB;
4523           if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4524           if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4525           FPSCR_SET_FR(0);
4526           FPSCR_SET_FI(0);
4527           GOTO(Done);
4528         /**/
4529         LABEL(Infinity_Operand):
4530           *frT = *frB;
4531           if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4532           if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4533           FPSCR_SET_FR(0);
4534           FPSCR_SET_FI(0);
4535           GOTO(Done);
4536         /**/
4537         LABEL(QNaN_Operand):
4538           *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4539           FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4540           FPSCR_SET_FR(0);
4541           FPSCR_SET_FI(0);
4542           GOTO(Done);
4543         /**/
4544         LABEL(SNaN_Operand):
4545           FPSCR_OR_VX(fpscr_vxsnan);
4546           if ((FPSCR & fpscr_ve) == 0) {
4547             *frT = (MASKED64(*frB, 0, 11)
4548                     | BIT64(12)
4549                     | MASKED64(*frB, 13, 34));
4550             FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4551           }
4552           FPSCR_SET_FR(0);
4553           FPSCR_SET_FI(0);
4554           GOTO(Done);
4555         /**/
4556         LABEL(Normal_Operand):
4557           sign = EXTRACTED64(*frB, 0, 0);
4558           exp = EXTRACTED64(*frB, 1, 11) - 1023;
4559           frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4560           Round_Single(processor, sign, &exp, &frac_grx);
4561           FPSCR_SET_XX(FPSCR & fpscr_fi);
4562           if (exp > 127 && (FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4563           if (exp > 127 && (FPSCR & fpscr_oe) != 0) GOTO(Enabled_Overflow);
4564           *frT = (INSERTED64(sign, 0, 0)
4565                   | INSERTED64(exp + 1023, 1, 11)
4566                   | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4567           if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4568           if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4569           GOTO(Done);
4570         /**/
4571         LABEL(Done):
4572           PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4573
4574
4575 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4576         floating_point_assist_interrupt(processor, cia);
4577
4578 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4579         floating_point_assist_interrupt(processor, cia);
4580
4581 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4582         floating_point_assist_interrupt(processor, cia);
4583
4584 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4585 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4586 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4587 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4588 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4589         FPSCR_BEGIN;
4590         convert_to_integer(processor, cia,
4591                            frT, *frB,
4592                            fpscr_rn_round_towards_zero, 32);
4593         FPSCR_END(Rc);
4594         PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4595
4596 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4597         int sign = EXTRACTED64(*frB, 0, 0);
4598         int exp = 63;
4599         unsigned64 frac = *frB;
4600         /***/
4601           if (frac == 0) GOTO(Zero_Operand);
4602           if (sign == 1) frac = ~frac + 1;
4603           while (EXTRACTED64(frac, 0, 0) == 0) {
4604             /*??? do the loop 0 times if (FRB) = max negative integer */
4605             frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4606             exp = exp - 1;
4607           }
4608           Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4609           if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4610           if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4611           *frT = (INSERTED64(sign, 0, 0)
4612                   | INSERTED64(exp + 1023, 1, 11)
4613                   | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4614           GOTO(Done);
4615         /**/
4616         LABEL(Zero_Operand):
4617           FPSCR_SET_FR(0);
4618           FPSCR_SET_FI(0);
4619           FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4620           *frT = 0;
4621           GOTO(Done);
4622         /**/
4623         LABEL(Done):
4624           PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4625
4626
4627 #
4628 # I.4.6.7 Floating-Point Compare Instructions
4629 #
4630
4631 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4632 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4633 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4634 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4635 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4636         FPSCR_BEGIN;
4637         unsigned c;
4638         if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4639           c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4640         else if (is_less_than(frA, frB))
4641           c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4642         else if (is_greater_than(frA, frB))
4643           c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4644         else
4645           c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4646         FPSCR_SET_FPCC(c);
4647         CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4648         if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4649           FPSCR_OR_VX(fpscr_vxsnan);
4650         FPSCR_END(0);
4651         PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4652
4653 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4654 *601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4655 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4656 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4657 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4658         FPSCR_BEGIN;
4659         unsigned c;
4660         if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4661           c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4662         else if (is_less_than(frA, frB))
4663           c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4664         else if (is_greater_than(frA, frB))
4665           c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4666         else
4667           c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4668         FPSCR_SET_FPCC(c);
4669         CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4670         if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4671           FPSCR_OR_VX(fpscr_vxsnan);
4672           if ((FPSCR & fpscr_ve) == 0)
4673             FPSCR_OR_VX(fpscr_vxvc);
4674         }
4675         else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4676           FPSCR_OR_VX(fpscr_vxvc);
4677         }
4678         FPSCR_END(0);
4679         PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4680
4681
4682 #
4683 # I.4.6.8 Floating-Point Status and Control Register Instructions
4684 #
4685
4686 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4687         FPSCR_BEGIN;
4688         *frT = FPSCR;
4689         FPSCR_END(Rc);
4690
4691 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4692         FPSCR_BEGIN;
4693         unsigned field = FPSCR_FIELD(BFA);
4694         CR_SET(BF, field);
4695         FPSCR_SET(BFA, 0); /* FPSCR_END fixes up FEX/VX */
4696         FPSCR_END(0);
4697
4698 0.63,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4699         FPSCR_BEGIN;
4700         FPSCR_SET(BF, U);
4701         FPSCR_END(Rc);
4702
4703 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4704         FPSCR_BEGIN;
4705         int i;
4706         for (i = 0; i < 8; i++) {
4707           if ((FLM & BIT8(i))) {
4708             FPSCR &= ~MASK32(i*4, i*4+3);
4709             FPSCR |= MASKED32(*frB, i*4, i*4+3);
4710           }
4711         }
4712         FPSCR_END(Rc);
4713
4714 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4715         FPSCR_BEGIN;
4716         unsigned32 bit = BIT32(BT);
4717         FPSCR &= ~bit;
4718         FPSCR_END(Rc);
4719
4720 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4721         FPSCR_BEGIN;
4722         unsigned32 bit = BIT32(BT);
4723         if (bit & fpscr_fi)
4724           bit |= fpscr_xx;
4725         if ((bit & fpscr_vx_bits))
4726           bit |= fpscr_fx;
4727         /* note - omit vx bit */
4728         if ((bit & (fpscr_ox | fpscr_ux | fpscr_zx | fpscr_xx)))
4729           bit |= fpscr_fx;
4730         FPSCR |= bit;
4731         FPSCR_END(Rc);
4732
4733 #
4734 # I.A.1.2 Floating-Point Arithmetic Instructions
4735 #
4736
4737 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root
4738         program_interrupt(processor, cia, optional_instruction_program_interrupt);
4739
4740 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root Single
4741         program_interrupt(processor, cia, optional_instruction_program_interrupt);
4742
4743 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f,o::Floating Reciprocal Estimate Single
4744         program_interrupt(processor, cia, optional_instruction_program_interrupt);
4745
4746 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f,o::Floating Reciprocal Square Root Estimate
4747         program_interrupt(processor, cia, optional_instruction_program_interrupt);
4748
4749 #
4750 # I.A.1.3 Floating-Point Select Instruction
4751 #
4752
4753 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f,o::Floating Select
4754 *601: PPC_UNIT_BAD,   PPC_UNIT_BAD,   0,  0,  0
4755 *603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4756 *603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4757 *604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4758         if (CURRENT_MODEL == MODEL_ppc601) {
4759           program_interrupt(processor, cia, optional_instruction_program_interrupt);
4760         } else {
4761           unsigned64 zero = 0;
4762           FPSCR_BEGIN;
4763           if (is_NaN(*frA, 0) || is_less_than (frA, &zero)) *frT = *frB;
4764           else                                              *frT = *frC;
4765           FPSCR_END(Rc);
4766           PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4767         }
4768
4769 #
4770 # II.3.2 Cache Management Instructions
4771 #
4772
4773 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4774 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4775 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4776 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4777 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4778         /* blindly flush all instruction cache entries */
4779         #if WITH_IDECODE_CACHE_SIZE
4780         cpu_flush_icache(processor);
4781         #endif
4782         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4783
4784 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4785 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4786 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4787 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4788 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4789         cpu_synchronize_context(processor, cia);
4790         PPC_INSN_INT(0, 0, 0);
4791
4792
4793 #
4794 # II.3.2.2 Data Cache Instructions
4795 #
4796
4797 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4798 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4799 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4800 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4801 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4802         TRACE(trace_tbd,("Data Cache Block Touch\n"));
4803         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4804
4805 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4806 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4807 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4808 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4809 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4810         TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4811         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4812
4813 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4814 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4815 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   10, 10, 0
4816 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   10, 10, 0
4817 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4818         TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4819         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4820
4821 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4822 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4823 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4824 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4825 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4826         TRACE(trace_tbd,("Data Cache Block Store\n"));
4827         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4828
4829 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4830 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4831 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4832 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4833 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4834         TRACE(trace_tbd,("Data Cache Block Flush\n"));
4835         PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4836
4837 #
4838 # II.3.3 Enforce In-order Execution of I/O Instruction
4839 #
4840
4841 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4842         /* Since this model has no instruction overlap
4843            this instruction need do nothing */
4844
4845 #
4846 # II.4.1 Time Base Instructions
4847 #
4848
4849 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4850 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4851 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4852 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
4853         int n = (tbr{5:9} << 5) | tbr{0:4};
4854         if (n == 268) {
4855           if (is_64bit_implementation) *rT = TB;
4856           else                         *rT = EXTRACTED64(TB, 32, 63);
4857         }
4858         else if (n == 269) {
4859           if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4860           else                         *rT = EXTRACTED64(TB, 0, 31);
4861         }
4862         else
4863           program_interrupt(processor, cia,
4864                             illegal_instruction_program_interrupt);
4865
4866
4867 #
4868 # III.2.3.1 System Linkage Instructions
4869 #
4870
4871 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4872 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4873 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4874 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4875 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
4876         if (IS_PROBLEM_STATE(processor)) {
4877           program_interrupt(processor, cia,
4878                             privileged_instruction_program_interrupt);
4879         }
4880         else {
4881           MSR = (MASKED(SRR1, 0, 32)
4882                  | MASKED(SRR1, 37, 41)
4883                  | MASKED(SRR1, 48, 63));
4884           NIA = MASKED(SRR0, 0, 61);
4885           cpu_synchronize_context(processor, cia);
4886           check_masked_interrupts(processor);
4887         }
4888
4889 #
4890 # III.3.4.1 Move to/from System Register Instructions
4891 #
4892
4893 #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4894 #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4895 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4896 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4897 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4898 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4899 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4900         if (IS_PROBLEM_STATE(processor))
4901           program_interrupt(processor, cia,
4902                             privileged_instruction_program_interrupt);
4903         else {
4904           MSR = *rS;
4905           check_masked_interrupts(processor);
4906         }
4907
4908 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4909 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4910 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4911 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4912 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
4913         if (IS_PROBLEM_STATE(processor))
4914           program_interrupt(processor, cia,
4915                             privileged_instruction_program_interrupt);
4916         else {
4917           *rT = MSR;
4918           check_masked_interrupts(processor);
4919         }
4920
4921
4922 #
4923 # III.4.11.1 Cache Management Instructions
4924 #
4925
4926 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4927 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4928 *603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4929 *603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4930 *604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4931         if (IS_PROBLEM_STATE(processor))
4932           program_interrupt(processor, cia,
4933                             privileged_instruction_program_interrupt);
4934         else
4935           TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4936
4937 #
4938 # III.4.11.2 Segment Register Manipulation Instructions
4939 #
4940
4941 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4942 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4943 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4944 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4945 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4946         if (IS_PROBLEM_STATE(processor))
4947           program_interrupt(processor, cia,
4948                             privileged_instruction_program_interrupt);
4949         else
4950           SEGREG(SR) = *rS;
4951
4952 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4953 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4954 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4955 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4956 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4957         if (IS_PROBLEM_STATE(processor))
4958           program_interrupt(processor, cia,
4959                             privileged_instruction_program_interrupt);
4960         else
4961           SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4962
4963 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4964 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
4965 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4966 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4967 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4968         if (IS_PROBLEM_STATE(processor))
4969           program_interrupt(processor, cia,
4970                             privileged_instruction_program_interrupt);
4971         else
4972           *rT = SEGREG(SR);
4973
4974 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4975 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
4976 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4977 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4978 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4979         if (IS_PROBLEM_STATE(processor))
4980           program_interrupt(processor, cia,
4981                             privileged_instruction_program_interrupt);
4982         else
4983           *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4984
4985
4986 #
4987 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4988 #
4989
4990 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4991
4992 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4993
4994 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4995         if (IS_PROBLEM_STATE(processor))
4996           program_interrupt(processor, cia,
4997                             privileged_instruction_program_interrupt);
4998         else {
4999           int nr = 0;
5000           cpu *proc;
5001           while (1) {
5002             proc = psim_cpu(cpu_system(processor), nr);
5003             if (proc == NULL) break;
5004             cpu_page_tlb_invalidate_entry(proc, *rB);
5005             nr++;
5006           }
5007         }
5008
5009 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
5010         if (IS_PROBLEM_STATE(processor))
5011           program_interrupt(processor, cia,
5012                             privileged_instruction_program_interrupt);
5013         else {
5014           int nr = 0;
5015           cpu *proc;
5016           while (1) {
5017             proc = psim_cpu(cpu_system(processor), nr);
5018             if (proc == NULL) break;
5019             cpu_page_tlb_invalidate_all(proc);
5020             nr++;
5021           }
5022         }
5023
5024 0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
5025         /* nothing happens here - always in sync */
5026
5027 #
5028 # III.A.1.2 External Access Instructions
5029 #
5030
5031 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
5032
5033 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
5034
5035 :include:::altivec.igen
5036 :include:::e500.igen