OSDN Git Service

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