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