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