OSDN Git Service

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