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