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