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