OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [ppc/] [ppc-instructions] - Blame information for rev 438

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
#
2
#   This file is part of the program psim.
3
#
4
#   Copyright 1994, 1995, 1996, 1997, 2003, 2004 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
 
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
 
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
 
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
 
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
 
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
 
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.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point Integer Word Indexed
3648
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3649
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3650
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3651
        unsigned_word b;
3652
        unsigned_word EA;
3653
        if (RA_is_0) b = 0;
3654
        else         b = *rA;
3655
        EA = b + *rB;
3656
        STORE(EA, 4, *frS);
3657
        PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3658
 
3659
0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3660
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3661
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3662
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3663
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3664
        unsigned_word EA;
3665
        if (RA_is_0)
3666
          program_interrupt(processor, cia,
3667
                            illegal_instruction_program_interrupt);
3668
        EA = *rA + EXTS(D);
3669
        STORE(EA, 8, *frS);
3670
        *rA = EA;
3671
        PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3672
 
3673
0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3674
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
3675
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3676
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  2,  0
3677
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
3678
        unsigned_word EA;
3679
        if (RA_is_0)
3680
          program_interrupt(processor, cia,
3681
                            illegal_instruction_program_interrupt);
3682
        EA = *rA + *rB;
3683
        STORE(EA, 8, *frS);
3684
        *rA = EA;
3685
        PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3686
 
3687
 
3688
#
3689
# I.4.6.4 Floating-Point Move Instructions
3690
#
3691
 
3692
0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3693
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3694
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3695
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3696
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3697
        *frT = *frB;
3698
        CR1_UPDATE(Rc);
3699
        PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3700
 
3701
0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3702
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3703
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3704
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3705
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3706
        *frT = *frB ^ BIT64(0);
3707
        CR1_UPDATE(Rc);
3708
        PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3709
 
3710
0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3711
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3712
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3713
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3714
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3715
        *frT = *frB & ~BIT64(0);
3716
        CR1_UPDATE(Rc);
3717
        PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3718
 
3719
0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3720
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3721
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3722
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3723
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3724
        *frT = *frB | BIT64(0);
3725
        CR1_UPDATE(Rc);
3726
        PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3727
 
3728
 
3729
#
3730
# I.4.6.5 Floating-Point Arithmetic Instructions
3731
#
3732
 
3733
0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3734
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3735
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3736
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3737
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3738
        FPSCR_BEGIN;
3739
        if (is_invalid_operation(processor, cia,
3740
                                 *frA, *frB,
3741
                                 fpscr_vxsnan | fpscr_vxisi,
3742
                                 0, /*single?*/
3743
                                 0) /*negate?*/) {
3744
          invalid_arithemetic_operation(processor, cia,
3745
                                        frT, *frA, *frB, 0,
3746
                                        0, /*instruction_is_frsp*/
3747
                                        0, /*instruction_is_convert_to_64bit*/
3748
                                        0, /*instruction_is_convert_to_32bit*/
3749
                                        0); /*single-precision*/
3750
        }
3751
        else {
3752
          /*HACK!*/
3753
          double s = *(double*)frA + *(double*)frB;
3754
          *(double*)frT = s;
3755
        }
3756
        FPSCR_END(Rc);
3757
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3758
 
3759
0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3760
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3761
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3762
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3763
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3764
        FPSCR_BEGIN;
3765
        if (is_invalid_operation(processor, cia,
3766
                                 *frA, *frB,
3767
                                 fpscr_vxsnan | fpscr_vxisi,
3768
                                 1, /*single?*/
3769
                                 0) /*negate?*/) {
3770
          invalid_arithemetic_operation(processor, cia,
3771
                                        frT, *frA, *frB, 0,
3772
                                        0, /*instruction_is_frsp*/
3773
                                        0, /*instruction_is_convert_to_64bit*/
3774
                                        0, /*instruction_is_convert_to_32bit*/
3775
                                        1); /*single-precision*/
3776
        }
3777
        else {
3778
          /*HACK!*/
3779
          float s = *(double*)frA + *(double*)frB;
3780
          *(double*)frT = s;
3781
        }
3782
        FPSCR_END(Rc);
3783
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3784
 
3785
0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3786
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3787
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3788
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3789
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3790
        FPSCR_BEGIN;
3791
        if (is_invalid_operation(processor, cia,
3792
                                 *frA, *frB,
3793
                                 fpscr_vxsnan | fpscr_vxisi,
3794
                                 0, /*single?*/
3795
                                 1) /*negate?*/) {
3796
          invalid_arithemetic_operation(processor, cia,
3797
                                        frT, *frA, *frB, 0,
3798
                                        0, /*instruction_is_frsp*/
3799
                                        0, /*instruction_is_convert_to_64bit*/
3800
                                        0, /*instruction_is_convert_to_32bit*/
3801
                                        0); /*single-precision*/
3802
        }
3803
        else {
3804
          /*HACK!*/
3805
          double s = *(double*)frA - *(double*)frB;
3806
          *(double*)frT = s;
3807
        }
3808
        FPSCR_END(Rc);
3809
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3810
 
3811
0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3812
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3813
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3814
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3815
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3816
        FPSCR_BEGIN;
3817
        if (is_invalid_operation(processor, cia,
3818
                                 *frA, *frB,
3819
                                 fpscr_vxsnan | fpscr_vxisi,
3820
                                 1, /*single?*/
3821
                                 1) /*negate?*/) {
3822
          invalid_arithemetic_operation(processor, cia,
3823
                                        frT, *frA, *frB, 0,
3824
                                        0, /*instruction_is_frsp*/
3825
                                        0, /*instruction_is_convert_to_64bit*/
3826
                                        0, /*instruction_is_convert_to_32bit*/
3827
                                        1); /*single-precision*/
3828
        }
3829
        else {
3830
          /*HACK!*/
3831
          float s = *(double*)frA - *(double*)frB;
3832
          *(double*)frT = s;
3833
        }
3834
        FPSCR_END(Rc);
3835
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3836
 
3837
0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3838
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
3839
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3840
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3841
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3842
        FPSCR_BEGIN;
3843
        if (is_invalid_operation(processor, cia,
3844
                                 *frA, *frC,
3845
                                 fpscr_vxsnan | fpscr_vximz,
3846
                                 0, /*single?*/
3847
                                 0) /*negate?*/) {
3848
          invalid_arithemetic_operation(processor, cia,
3849
                                        frT, *frA, 0, *frC,
3850
                                        0, /*instruction_is_frsp*/
3851
                                        0, /*instruction_is_convert_to_64bit*/
3852
                                        0, /*instruction_is_convert_to_32bit*/
3853
                                        0); /*single-precision*/
3854
        }
3855
        else {
3856
          /*HACK!*/
3857
          double s = *(double*)frA * *(double*)frC;
3858
          *(double*)frT = s;
3859
        }
3860
        FPSCR_END(Rc);
3861
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3862
 
3863
0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3864
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
3865
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3866
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3867
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3868
        FPSCR_BEGIN;
3869
        if (is_invalid_operation(processor, cia,
3870
                                 *frA, *frC,
3871
                                 fpscr_vxsnan | fpscr_vximz,
3872
                                 1, /*single?*/
3873
                                 0) /*negate?*/) {
3874
          invalid_arithemetic_operation(processor, cia,
3875
                                        frT, *frA, 0, *frC,
3876
                                        0, /*instruction_is_frsp*/
3877
                                        0, /*instruction_is_convert_to_64bit*/
3878
                                        0, /*instruction_is_convert_to_32bit*/
3879
                                        1); /*single-precision*/
3880
        }
3881
        else {
3882
          /*HACK!*/
3883
          float s = *(double*)frA * *(double*)frC;
3884
          *(double*)frT = s;
3885
        }
3886
        FPSCR_END(Rc);
3887
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3888
 
3889
0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3890
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   31, 31, 0
3891
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   33, 33, 0
3892
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   33, 33, 0
3893
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   32, 32, 0
3894
        FPSCR_BEGIN;
3895
        if (is_invalid_operation(processor, cia,
3896
                                 *frA, *frB,
3897
                                 fpscr_vxsnan | fpscr_vxzdz,
3898
                                 0, /*single?*/
3899
                                 0) /*negate?*/) {
3900
          invalid_arithemetic_operation(processor, cia,
3901
                                        frT, *frA, *frB, 0,
3902
                                        0, /*instruction_is_frsp*/
3903
                                        0, /*instruction_is_convert_to_64bit*/
3904
                                        0, /*instruction_is_convert_to_32bit*/
3905
                                        0); /*single-precision*/
3906
        }
3907
        else if (is_invalid_zero_divide (processor, cia,
3908
                                         *frA, *frB,
3909
 
3910
          invalid_zero_divide_operation (processor, cia,
3911
                                         frT, *frA, *frB,
3912
 
3913
        }
3914
        else {
3915
          /*HACK!*/
3916
          double s = *(double*)frA / *(double*)frB;
3917
          *(double*)frT = s;
3918
        }
3919
        FPSCR_END(Rc);
3920
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3921
 
3922
0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3923
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   17, 17, 0
3924
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
3925
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
3926
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   18, 18, 0
3927
        FPSCR_BEGIN;
3928
        if (is_invalid_operation(processor, cia,
3929
                                 *frA, *frB,
3930
                                 fpscr_vxsnan | fpscr_vxzdz,
3931
                                 1, /*single?*/
3932
                                 0) /*negate?*/) {
3933
          invalid_arithemetic_operation(processor, cia,
3934
                                        frT, *frA, *frB, 0,
3935
                                        0, /*instruction_is_frsp*/
3936
                                        0, /*instruction_is_convert_to_64bit*/
3937
                                        0, /*instruction_is_convert_to_32bit*/
3938
                                        1); /*single-precision*/
3939
        }
3940
        else if (is_invalid_zero_divide (processor, cia,
3941
                                         *frA, *frB,
3942
                                         1 /*single?*/)) {
3943
          invalid_zero_divide_operation (processor, cia,
3944
                                         frT, *frA, *frB,
3945
                                         1 /*single?*/);
3946
        }
3947
        else {
3948
          /*HACK!*/
3949
          float s = *(double*)frA / *(double*)frB;
3950
          *(double*)frT = s;
3951
        }
3952
        FPSCR_END(Rc);
3953
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3954
 
3955
0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3956
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
3957
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3958
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
3959
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
3960
        FPSCR_BEGIN;
3961
        double product; /*HACK! - incorrectly loosing precision ... */
3962
        /* compute the multiply */
3963
        if (is_invalid_operation(processor, cia,
3964
                                 *frA, *frC,
3965
                                 fpscr_vxsnan | fpscr_vximz,
3966
                                 0, /*single?*/
3967
                                 0) /*negate?*/) {
3968
          invalid_arithemetic_operation(processor, cia,
3969
                                        (unsigned64*)&product, *frA, 0, *frC,
3970
                                        0, /*instruction_is_frsp*/
3971
                                        0, /*instruction_is_convert_to_64bit*/
3972
                                        0, /*instruction_is_convert_to_32bit*/
3973
                                        0); /*single-precision*/
3974
        }
3975
        else {
3976
          /*HACK!*/
3977
          product = *(double*)frA * *(double*)frC;
3978
        }
3979
        /* compute the add */
3980
        if (is_invalid_operation(processor, cia,
3981
                                 product, *frB,
3982
                                 fpscr_vxsnan | fpscr_vxisi,
3983
                                 0, /*single?*/
3984
                                 0) /*negate?*/) {
3985
          invalid_arithemetic_operation(processor, cia,
3986
                                        frT, product, *frB, 0,
3987
                                        0, /*instruction_is_frsp*/
3988
                                        0, /*instruction_is_convert_to_64bit*/
3989
                                        0, /*instruction_is_convert_to_32bit*/
3990
                                        0); /*single-precision*/
3991
        }
3992
        else {
3993
          /*HACK!*/
3994
          double s = product + *(double*)frB;
3995
          *(double*)frT = s;
3996
        }
3997
        FPSCR_END(Rc);
3998
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3999
 
4000
0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
4001
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4002
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4003
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4004
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4005
        FPSCR_BEGIN;
4006
        float product; /*HACK! - incorrectly loosing precision ... */
4007
        /* compute the multiply */
4008
        if (is_invalid_operation(processor, cia,
4009
                                 *frA, *frC,
4010
                                 fpscr_vxsnan | fpscr_vximz,
4011
                                 1, /*single?*/
4012
                                 0) /*negate?*/) {
4013
          invalid_arithemetic_operation(processor, cia,
4014
                                        (unsigned64*)&product, *frA, 0, *frC,
4015
                                        0, /*instruction_is_frsp*/
4016
                                        0, /*instruction_is_convert_to_64bit*/
4017
                                        0, /*instruction_is_convert_to_32bit*/
4018
                                        0); /*single-precision*/
4019
        }
4020
        else {
4021
          /*HACK!*/
4022
          product = *(double*)frA * *(double*)frC;
4023
        }
4024
        /* compute the add */
4025
        if (is_invalid_operation(processor, cia,
4026
                                 product, *frB,
4027
                                 fpscr_vxsnan | fpscr_vxisi,
4028
                                 1, /*single?*/
4029
                                 0) /*negate?*/) {
4030
          invalid_arithemetic_operation(processor, cia,
4031
                                        frT, product, *frB, 0,
4032
                                        0, /*instruction_is_frsp*/
4033
                                        0, /*instruction_is_convert_to_64bit*/
4034
                                        0, /*instruction_is_convert_to_32bit*/
4035
                                        0); /*single-precision*/
4036
        }
4037
        else {
4038
          /*HACK!*/
4039
          float s = product + *(double*)frB;
4040
          *(double*)frT = (double)s;
4041
        }
4042
        FPSCR_END(Rc);
4043
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4044
 
4045
0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
4046
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
4047
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4048
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4049
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4050
        FPSCR_BEGIN;
4051
        double product; /*HACK! - incorrectly loosing precision ... */
4052
        /* compute the multiply */
4053
        if (is_invalid_operation(processor, cia,
4054
                                 *frA, *frC,
4055
                                 fpscr_vxsnan | fpscr_vximz,
4056
                                 0, /*single?*/
4057
                                 0) /*negate?*/) {
4058
          invalid_arithemetic_operation(processor, cia,
4059
                                        (unsigned64*)&product, *frA, 0, *frC,
4060
                                        0, /*instruction_is_frsp*/
4061
                                        0, /*instruction_is_convert_to_64bit*/
4062
                                        0, /*instruction_is_convert_to_32bit*/
4063
                                        0); /*single-precision*/
4064
        }
4065
        else {
4066
          /*HACK!*/
4067
          product = *(double*)frA * *(double*)frC;
4068
        }
4069
        /* compute the subtract */
4070
        if (is_invalid_operation(processor, cia,
4071
                                 product, *frB,
4072
                                 fpscr_vxsnan | fpscr_vxisi,
4073
                                 0, /*single?*/
4074
                                 0) /*negate?*/) {
4075
          invalid_arithemetic_operation(processor, cia,
4076
                                        frT, product, *frB, 0,
4077
                                        0, /*instruction_is_frsp*/
4078
                                        0, /*instruction_is_convert_to_64bit*/
4079
                                        0, /*instruction_is_convert_to_32bit*/
4080
                                        0); /*single-precision*/
4081
        }
4082
        else {
4083
          /*HACK!*/
4084
          double s = product - *(double*)frB;
4085
          *(double*)frT = s;
4086
        }
4087
        FPSCR_END(Rc);
4088
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4089
 
4090
0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
4091
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4092
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4093
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4094
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4095
        FPSCR_BEGIN;
4096
        float product; /*HACK! - incorrectly loosing precision ... */
4097
        /* compute the multiply */
4098
        if (is_invalid_operation(processor, cia,
4099
                                 *frA, *frC,
4100
                                 fpscr_vxsnan | fpscr_vximz,
4101
                                 1, /*single?*/
4102
                                 0) /*negate?*/) {
4103
          invalid_arithemetic_operation(processor, cia,
4104
                                        (unsigned64*)&product, *frA, 0, *frC,
4105
                                        0, /*instruction_is_frsp*/
4106
                                        0, /*instruction_is_convert_to_64bit*/
4107
                                        0, /*instruction_is_convert_to_32bit*/
4108
                                        0); /*single-precision*/
4109
        }
4110
        else {
4111
          /*HACK!*/
4112
          product = *(double*)frA * *(double*)frC;
4113
        }
4114
        /* compute the subtract */
4115
        if (is_invalid_operation(processor, cia,
4116
                                 product, *frB,
4117
                                 fpscr_vxsnan | fpscr_vxisi,
4118
                                 1, /*single?*/
4119
                                 0) /*negate?*/) {
4120
          invalid_arithemetic_operation(processor, cia,
4121
                                        frT, product, *frB, 0,
4122
                                        0, /*instruction_is_frsp*/
4123
                                        0, /*instruction_is_convert_to_64bit*/
4124
                                        0, /*instruction_is_convert_to_32bit*/
4125
                                        0); /*single-precision*/
4126
        }
4127
        else {
4128
          /*HACK!*/
4129
          float s = product - *(double*)frB;
4130
          *(double*)frT = (double)s;
4131
        }
4132
        FPSCR_END(Rc);
4133
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4134
 
4135
0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
4136
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
4137
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4138
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4139
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4140
        FPSCR_BEGIN;
4141
        double product; /*HACK! - incorrectly loosing precision ... */
4142
        /* compute the multiply */
4143
        if (is_invalid_operation(processor, cia,
4144
                                 *frA, *frC,
4145
                                 fpscr_vxsnan | fpscr_vximz,
4146
                                 0, /*single?*/
4147
                                 0) /*negate?*/) {
4148
          invalid_arithemetic_operation(processor, cia,
4149
                                        (unsigned64*)&product, *frA, 0, *frC,
4150
                                        0, /*instruction_is_frsp*/
4151
                                        0, /*instruction_is_convert_to_64bit*/
4152
                                        0, /*instruction_is_convert_to_32bit*/
4153
                                        0); /*single-precision*/
4154
        }
4155
        else {
4156
          /*HACK!*/
4157
          product = *(double*)frA * *(double*)frC;
4158
        }
4159
        /* compute the add */
4160
        if (is_invalid_operation(processor, cia,
4161
                                 product, *frB,
4162
                                 fpscr_vxsnan | fpscr_vxisi,
4163
                                 0, /*single?*/
4164
                                 0) /*negate?*/) {
4165
          invalid_arithemetic_operation(processor, cia,
4166
                                        frT, product, *frB, 0,
4167
                                        0, /*instruction_is_frsp*/
4168
                                        0, /*instruction_is_convert_to_64bit*/
4169
                                        0, /*instruction_is_convert_to_32bit*/
4170
                                        0); /*single-precision*/
4171
        }
4172
        else {
4173
          /*HACK!*/
4174
          double s = -(product + *(double*)frB);
4175
          *(double*)frT = s;
4176
        }
4177
        FPSCR_END(Rc);
4178
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4179
 
4180
0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
4181
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4182
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4183
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4184
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4185
        FPSCR_BEGIN;
4186
        float product; /*HACK! - incorrectly loosing precision ... */
4187
        /* compute the multiply */
4188
        if (is_invalid_operation(processor, cia,
4189
                                 *frA, *frC,
4190
                                 fpscr_vxsnan | fpscr_vximz,
4191
                                 1, /*single?*/
4192
                                 0) /*negate?*/) {
4193
          invalid_arithemetic_operation(processor, cia,
4194
                                        (unsigned64*)&product, *frA, 0, *frC,
4195
                                        0, /*instruction_is_frsp*/
4196
                                        0, /*instruction_is_convert_to_64bit*/
4197
                                        0, /*instruction_is_convert_to_32bit*/
4198
                                        0); /*single-precision*/
4199
        }
4200
        else {
4201
          /*HACK!*/
4202
          product = *(double*)frA * *(double*)frC;
4203
        }
4204
        /* compute the add */
4205
        if (is_invalid_operation(processor, cia,
4206
                                 product, *frB,
4207
                                 fpscr_vxsnan | fpscr_vxisi,
4208
                                 1, /*single?*/
4209
                                 0) /*negate?*/) {
4210
          invalid_arithemetic_operation(processor, cia,
4211
                                        frT, product, *frB, 0,
4212
                                        0, /*instruction_is_frsp*/
4213
                                        0, /*instruction_is_convert_to_64bit*/
4214
                                        0, /*instruction_is_convert_to_32bit*/
4215
                                        0); /*single-precision*/
4216
        }
4217
        else {
4218
          /*HACK!*/
4219
          float s = -(product + *(double*)frB);
4220
          *(double*)frT = (double)s;
4221
        }
4222
        FPSCR_END(Rc);
4223
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4224
 
4225
0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
4226
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   5,  5,  0
4227
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4228
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   2,  4,  0
4229
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4230
        FPSCR_BEGIN;
4231
        double product; /*HACK! - incorrectly loosing precision ... */
4232
        /* compute the multiply */
4233
        if (is_invalid_operation(processor, cia,
4234
                                 *frA, *frC,
4235
                                 fpscr_vxsnan | fpscr_vximz,
4236
                                 0, /*single?*/
4237
                                 0) /*negate?*/) {
4238
          invalid_arithemetic_operation(processor, cia,
4239
                                        (unsigned64*)&product, *frA, 0, *frC,
4240
                                        0, /*instruction_is_frsp*/
4241
                                        0, /*instruction_is_convert_to_64bit*/
4242
                                        0, /*instruction_is_convert_to_32bit*/
4243
                                        0); /*single-precision*/
4244
        }
4245
        else {
4246
          /*HACK!*/
4247
          product = *(double*)frA * *(double*)frC;
4248
        }
4249
        /* compute the subtract */
4250
        if (is_invalid_operation(processor, cia,
4251
                                 product, *frB,
4252
                                 fpscr_vxsnan | fpscr_vxisi,
4253
                                 0, /*single?*/
4254
                                 0) /*negate?*/) {
4255
          invalid_arithemetic_operation(processor, cia,
4256
                                        frT, product, *frB, 0,
4257
                                        0, /*instruction_is_frsp*/
4258
                                        0, /*instruction_is_convert_to_64bit*/
4259
                                        0, /*instruction_is_convert_to_32bit*/
4260
                                        0); /*single-precision*/
4261
        }
4262
        else {
4263
          /*HACK!*/
4264
          double s = -(product - *(double*)frB);
4265
          *(double*)frT = s;
4266
        }
4267
        FPSCR_END(Rc);
4268
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4269
 
4270
0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
4271
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4272
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4273
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4274
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4275
        FPSCR_BEGIN;
4276
        float product; /*HACK! - incorrectly loosing precision ... */
4277
        /* compute the multiply */
4278
        if (is_invalid_operation(processor, cia,
4279
                                 *frA, *frC,
4280
                                 fpscr_vxsnan | fpscr_vximz,
4281
                                 1, /*single?*/
4282
                                 0) /*negate?*/) {
4283
          invalid_arithemetic_operation(processor, cia,
4284
                                        (unsigned64*)&product, *frA, 0, *frC,
4285
                                        0, /*instruction_is_frsp*/
4286
                                        0, /*instruction_is_convert_to_64bit*/
4287
                                        0, /*instruction_is_convert_to_32bit*/
4288
                                        0); /*single-precision*/
4289
        }
4290
        else {
4291
          /*HACK!*/
4292
          product = *(double*)frA * *(double*)frC;
4293
        }
4294
        /* compute the subtract */
4295
        if (is_invalid_operation(processor, cia,
4296
                                 product, *frB,
4297
                                 fpscr_vxsnan | fpscr_vxisi,
4298
                                 1, /*single?*/
4299
                                 0) /*negate?*/) {
4300
          invalid_arithemetic_operation(processor, cia,
4301
                                        frT, product, *frB, 0,
4302
                                        0, /*instruction_is_frsp*/
4303
                                        0, /*instruction_is_convert_to_64bit*/
4304
                                        0, /*instruction_is_convert_to_32bit*/
4305
                                        0); /*single-precision*/
4306
        }
4307
        else {
4308
          /*HACK!*/
4309
          float s = -(product - *(double*)frB);
4310
          *(double*)frT = (double)s;
4311
        }
4312
        FPSCR_END(Rc);
4313
        PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4314
 
4315
 
4316
#
4317
# I.4.6.6 Floating-Point Rounding and Conversion Instructions
4318
#
4319
 
4320
0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4321
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4322
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4323
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4324
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4325
        int sign;
4326
        int exp;
4327
        unsigned64 frac_grx;
4328
        /***/
4329
          /* split off cases for what to do */
4330
          if (EXTRACTED64(*frB, 1, 11) < 897
4331
              && EXTRACTED64(*frB, 1, 63) > 0) {
4332
              if ((FPSCR & fpscr_ue) == 0) GOTO(Disabled_Exponent_Underflow);
4333
              if ((FPSCR & fpscr_ue) != 0) GOTO(Enabled_Exponent_Underflow);
4334
          }
4335
          if (EXTRACTED64(*frB, 1, 11) > 1150
4336
              && EXTRACTED64(*frB, 1, 11) < 2047) {
4337
              if ((FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4338
              if ((FPSCR & fpscr_oe) != 0) GOTO(Enabled_Exponent_Overflow);
4339
          }
4340
          if (EXTRACTED64(*frB, 1, 11) > 896
4341
              && EXTRACTED64(*frB, 1, 11) < 1151) GOTO(Normal_Operand);
4342
          if (EXTRACTED64(*frB, 1, 63) == 0) GOTO(Zero_Operand);
4343
          if (EXTRACTED64(*frB, 1, 11) == 2047) {
4344
            if (EXTRACTED64(*frB, 12, 63) == 0) GOTO(Infinity_Operand);
4345
            if (EXTRACTED64(*frB, 12, 12) == 1) GOTO(QNaN_Operand);
4346
            if (EXTRACTED64(*frB, 12, 12) == 0
4347
                && EXTRACTED64(*frB, 13, 63) > 0) GOTO(SNaN_Operand);
4348
          }
4349
        /**/
4350
        LABEL(Disabled_Exponent_Underflow):
4351
          sign = EXTRACTED64(*frB, 0, 0);
4352
          if (EXTRACTED64(*frB, 1, 11) == 0) {
4353
            exp = -1022;
4354
            frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4355
          }
4356
          if (EXTRACTED64(*frB, 1, 11) > 0) {
4357
            exp = EXTRACTED64(*frB, 1, 11) - 1023;
4358
            frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4359
          }
4360
            /* G|R|X == zero from above */
4361
            while (exp < -126) {
4362
              exp = exp + 1;
4363
              frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4364
                          | MASKED64(frac_grx, 55, 55));
4365
            }
4366
          FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4367
          Round_Single(processor, sign, &exp, &frac_grx);
4368
          FPSCR_SET_XX(FPSCR & fpscr_fi);
4369
          if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4370
            *frT = INSERTED64(sign, 0, 0);
4371
            if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4372
            if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4373
          }
4374
          if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4375
            if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4376
              if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4377
              if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4378
            }
4379
            if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4380
              if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4381
              if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4382
            }
4383
            /*Normalize_Operand:*/
4384
              while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4385
                exp = exp - 1;
4386
                frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1,  52), 0, 51);
4387
              }
4388
            *frT = (INSERTED64(sign, 0, 0)
4389
                    | INSERTED64(exp + 1023, 1, 11)
4390
                    | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4391
          }
4392
          GOTO(Done);
4393
        /**/
4394
        LABEL(Enabled_Exponent_Underflow):
4395
          FPSCR_SET_UX(1);
4396
          sign = EXTRACTED64(*frB, 0, 0);
4397
          if (EXTRACTED64(*frB, 1, 11) == 0) {
4398
            exp = -1022;
4399
            frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4400
          }
4401
          if (EXTRACTED64(*frB, 1, 11) > 0) {
4402
            exp = EXTRACTED64(*frB, 1, 11) - 1023;
4403
            frac_grx = (BIT64(0) |
4404
                        INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4405
          }
4406
          /*Normalize_Operand:*/
4407
            while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4408
              exp = exp - 1;
4409
              frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4410
            }
4411
          Round_Single(processor, sign, &exp, &frac_grx);
4412
          FPSCR_SET_XX(FPSCR & fpscr_fi);
4413
          exp = exp + 192;
4414
          *frT = (INSERTED64(sign, 0, 0)
4415
                  | INSERTED64(exp + 1023, 1, 11)
4416
                  | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4417
          if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4418
          if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4419
          GOTO(Done);
4420
        /**/
4421
        LABEL(Disabled_Exponent_Overflow):
4422
          FPSCR_SET_OX(1);
4423
          if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4424
            if (EXTRACTED64(*frB, 0, 0) == 0) {
4425
              *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4426
              FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4427
            }
4428
            if (EXTRACTED64(*frB, 0, 0) == 1) {
4429
              *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4430
              FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4431
            }
4432
          }
4433
          if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4434
            if (EXTRACTED64(*frB, 0, 0) == 0) {
4435
              *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4436
              FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4437
            }
4438
            if (EXTRACTED64(*frB, 0, 0) == 1) {
4439
              *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4440
              FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4441
            }
4442
          }
4443
          if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4444
            if (EXTRACTED64(*frB, 0, 0) == 0) {
4445
              *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4446
              FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4447
            }
4448
            if (EXTRACTED64(*frB, 0, 0) == 1) {
4449
              *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4450
              FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4451
            }
4452
          }
4453
          if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4454
            if (EXTRACTED64(*frB, 0, 0) == 0) {
4455
              *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4456
              FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4457
            }
4458
            if (EXTRACTED64(*frB, 0, 0) == 1) {
4459
              *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4460
              FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4461
            }
4462
          }
4463
          /* FPSCR[FR] <- undefined */
4464
          FPSCR_SET_FI(1);
4465
          FPSCR_SET_XX(1);
4466
          GOTO(Done);
4467
        /**/
4468
        LABEL(Enabled_Exponent_Overflow):
4469
          sign = EXTRACTED64(*frB, 0, 0);
4470
          exp = EXTRACTED64(*frB, 1, 11) - 1023;
4471
          frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4472
          Round_Single(processor, sign, &exp, &frac_grx);
4473
          FPSCR_SET_XX(FPSCR & fpscr_fi);
4474
        /**/
4475
        LABEL(Enabled_Overflow):
4476
          FPSCR_SET_OX(1);
4477
          exp = exp - 192;
4478
          *frT = (INSERTED64(sign, 0, 0)
4479
                  | INSERTED64(exp + 1023, 1, 11)
4480
                  | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4481
          if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4482
          if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4483
          GOTO(Done);
4484
        /**/
4485
        LABEL(Zero_Operand):
4486
          *frT = *frB;
4487
          if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4488
          if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4489
          FPSCR_SET_FR(0);
4490
          FPSCR_SET_FI(0);
4491
          GOTO(Done);
4492
        /**/
4493
        LABEL(Infinity_Operand):
4494
          *frT = *frB;
4495
          if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4496
          if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4497
          FPSCR_SET_FR(0);
4498
          FPSCR_SET_FI(0);
4499
          GOTO(Done);
4500
        /**/
4501
        LABEL(QNaN_Operand):
4502
          *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4503
          FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4504
          FPSCR_SET_FR(0);
4505
          FPSCR_SET_FI(0);
4506
          GOTO(Done);
4507
        /**/
4508
        LABEL(SNaN_Operand):
4509
          FPSCR_OR_VX(fpscr_vxsnan);
4510
          if ((FPSCR & fpscr_ve) == 0) {
4511
            *frT = (MASKED64(*frB, 0, 11)
4512
                    | BIT64(12)
4513
                    | MASKED64(*frB, 13, 34));
4514
            FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4515
          }
4516
          FPSCR_SET_FR(0);
4517
          FPSCR_SET_FI(0);
4518
          GOTO(Done);
4519
        /**/
4520
        LABEL(Normal_Operand):
4521
          sign = EXTRACTED64(*frB, 0, 0);
4522
          exp = EXTRACTED64(*frB, 1, 11) - 1023;
4523
          frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4524
          Round_Single(processor, sign, &exp, &frac_grx);
4525
          FPSCR_SET_XX(FPSCR & fpscr_fi);
4526
          if (exp > 127 && (FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4527
          if (exp > 127 && (FPSCR & fpscr_oe) != 0) GOTO(Enabled_Overflow);
4528
          *frT = (INSERTED64(sign, 0, 0)
4529
                  | INSERTED64(exp + 1023, 1, 11)
4530
                  | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4531
          if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4532
          if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4533
          GOTO(Done);
4534
        /**/
4535
        LABEL(Done):
4536
          PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4537
 
4538
 
4539
0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4540
        floating_point_assist_interrupt(processor, cia);
4541
 
4542
0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4543
        floating_point_assist_interrupt(processor, cia);
4544
 
4545
0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4546
        floating_point_assist_interrupt(processor, cia);
4547
 
4548
0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4549
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4550
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4551
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4552
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4553
        FPSCR_BEGIN;
4554
        convert_to_integer(processor, cia,
4555
                           frT, *frB,
4556
                           fpscr_rn_round_towards_zero, 32);
4557
        FPSCR_END(Rc);
4558
        PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4559
 
4560
0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4561
        int sign = EXTRACTED64(*frB, 0, 0);
4562
        int exp = 63;
4563
        unsigned64 frac = *frB;
4564
        /***/
4565
          if (frac == 0) GOTO(Zero_Operand);
4566
          if (sign == 1) frac = ~frac + 1;
4567
          while (EXTRACTED64(frac, 0, 0) == 0) {
4568
            /*??? do the loop 0 times if (FRB) = max negative integer */
4569
            frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4570
            exp = exp - 1;
4571
          }
4572
          Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4573
          if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4574
          if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4575
          *frT = (INSERTED64(sign, 0, 0)
4576
                  | INSERTED64(exp + 1023, 1, 11)
4577
                  | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4578
          GOTO(Done);
4579
        /**/
4580
        LABEL(Zero_Operand):
4581
          FPSCR_SET_FR(0);
4582
          FPSCR_SET_FI(0);
4583
          FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4584
          *frT = 0;
4585
          GOTO(Done);
4586
        /**/
4587
        LABEL(Done):
4588
          PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4589
 
4590
 
4591
#
4592
# I.4.6.7 Floating-Point Compare Instructions
4593
#
4594
 
4595
0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4596
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4597
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4598
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4599
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4600
        FPSCR_BEGIN;
4601
        unsigned c;
4602
        if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4603
          c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4604
        else if (is_less_than(frA, frB))
4605
          c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4606
        else if (is_greater_than(frA, frB))
4607
          c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4608
        else
4609
          c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4610
        FPSCR_SET_FPCC(c);
4611
        CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4612
        if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4613
          FPSCR_OR_VX(fpscr_vxsnan);
4614
        FPSCR_END(0);
4615
        PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4616
 
4617
0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4618
*601: PPC_UNIT_FPU,   PPC_UNIT_FPU,   4,  4,  0
4619
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4620
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4621
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4622
        FPSCR_BEGIN;
4623
        unsigned c;
4624
        if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4625
          c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4626
        else if (is_less_than(frA, frB))
4627
          c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4628
        else if (is_greater_than(frA, frB))
4629
          c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4630
        else
4631
          c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4632
        FPSCR_SET_FPCC(c);
4633
        CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4634
        if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4635
          FPSCR_OR_VX(fpscr_vxsnan);
4636
          if ((FPSCR & fpscr_ve) == 0)
4637
            FPSCR_OR_VX(fpscr_vxvc);
4638
        }
4639
        else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4640
          FPSCR_OR_VX(fpscr_vxvc);
4641
        }
4642
        FPSCR_END(0);
4643
        PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4644
 
4645
 
4646
#
4647
# I.4.6.8 Floating-Point Status and Control Register Instructions
4648
#
4649
 
4650
0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4651
        FPSCR_BEGIN;
4652
        *frT = FPSCR;
4653
        FPSCR_END(Rc);
4654
 
4655
0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4656
        FPSCR_BEGIN;
4657
        unsigned field = FPSCR_FIELD(BFA);
4658
        CR_SET(BF, field);
4659
        FPSCR_SET(BFA, 0); /* FPSCR_END fixes up FEX/VX */
4660
        FPSCR_END(0);
4661
 
4662
0.63,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4663
        FPSCR_BEGIN;
4664
        FPSCR_SET(BF, U);
4665
        FPSCR_END(Rc);
4666
 
4667
0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4668
        FPSCR_BEGIN;
4669
        int i;
4670
        for (i = 0; i < 8; i++) {
4671
          if ((FLM & BIT8(i))) {
4672
            FPSCR &= ~MASK32(i*4, i*4+3);
4673
            FPSCR |= MASKED32(*frB, i*4, i*4+3);
4674
          }
4675
        }
4676
        FPSCR_END(Rc);
4677
 
4678
0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4679
        FPSCR_BEGIN;
4680
        unsigned32 bit = BIT32(BT);
4681
        FPSCR &= ~bit;
4682
        FPSCR_END(Rc);
4683
 
4684
0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4685
        FPSCR_BEGIN;
4686
        unsigned32 bit = BIT32(BT);
4687
        if (bit & fpscr_fi)
4688
          bit |= fpscr_xx;
4689
        if ((bit & fpscr_vx_bits))
4690
          bit |= fpscr_fx;
4691
        /* note - omit vx bit */
4692
        if ((bit & (fpscr_ox | fpscr_ux | fpscr_zx | fpscr_xx)))
4693
          bit |= fpscr_fx;
4694
        FPSCR |= bit;
4695
        FPSCR_END(Rc);
4696
 
4697
#
4698
# I.A.1.2 Floating-Point Arithmetic Instructions
4699
#
4700
 
4701
0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root
4702
        program_interrupt(processor, cia, optional_instruction_program_interrupt);
4703
 
4704
0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root Single
4705
        program_interrupt(processor, cia, optional_instruction_program_interrupt);
4706
 
4707
0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f,o::Floating Reciprocal Estimate Single
4708
        program_interrupt(processor, cia, optional_instruction_program_interrupt);
4709
 
4710
0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f,o::Floating Reciprocal Square Root Estimate
4711
        program_interrupt(processor, cia, optional_instruction_program_interrupt);
4712
 
4713
#
4714
# I.A.1.3 Floating-Point Select Instruction
4715
#
4716
 
4717
0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f,o::Floating Select
4718
*601: PPC_UNIT_BAD,   PPC_UNIT_BAD,   0,  0,  0
4719
*603: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4720
*603e:PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4721
*604: PPC_UNIT_FPU,   PPC_UNIT_FPU,   1,  3,  0
4722
        if (CURRENT_MODEL == MODEL_ppc601) {
4723
          program_interrupt(processor, cia, optional_instruction_program_interrupt);
4724
        } else {
4725
          unsigned64 zero = 0;
4726
          FPSCR_BEGIN;
4727
          if (is_NaN(*frA, 0) || is_less_than (frA, &zero)) *frT = *frB;
4728
          else                                              *frT = *frC;
4729
          FPSCR_END(Rc);
4730
          PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4731
        }
4732
 
4733
#
4734
# II.3.2 Cache Management Instructions
4735
#
4736
 
4737
0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4738
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4739
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4740
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4741
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4742
        /* blindly flush all instruction cache entries */
4743
        #if WITH_IDECODE_CACHE_SIZE
4744
        cpu_flush_icache(processor);
4745
        #endif
4746
        PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4747
 
4748
0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4749
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4750
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4751
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4752
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4753
        cpu_synchronize_context(processor, cia);
4754
        PPC_INSN_INT(0, 0, 0);
4755
 
4756
 
4757
#
4758
# II.3.2.2 Data Cache Instructions
4759
#
4760
 
4761
0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4762
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4763
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4764
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4765
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4766
        TRACE(trace_tbd,("Data Cache Block Touch\n"));
4767
        PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4768
 
4769
0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4770
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4771
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4772
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4773
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4774
        TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4775
        PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4776
 
4777
0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4778
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4779
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   10, 10, 0
4780
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   10, 10, 0
4781
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4782
        TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4783
        PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4784
 
4785
0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4786
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4787
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4788
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4789
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4790
        TRACE(trace_tbd,("Data Cache Block Store\n"));
4791
        PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4792
 
4793
0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4794
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4795
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4796
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   5,  5,  0
4797
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  1,  0
4798
        TRACE(trace_tbd,("Data Cache Block Flush\n"));
4799
        PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4800
 
4801
#
4802
# II.3.3 Enforce In-order Execution of I/O Instruction
4803
#
4804
 
4805
0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4806
        /* Since this model has no instruction overlap
4807
           this instruction need do nothing */
4808
 
4809
#
4810
# II.4.1 Time Base Instructions
4811
#
4812
 
4813
0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4814
*603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4815
*603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4816
*604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
4817
        int n = (tbr{5:9} << 5) | tbr{0:4};
4818
        if (n == 268) {
4819
          if (is_64bit_implementation) *rT = TB;
4820
          else                         *rT = EXTRACTED64(TB, 32, 63);
4821
        }
4822
        else if (n == 269) {
4823
          if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4824
          else                         *rT = EXTRACTED64(TB, 0, 31);
4825
        }
4826
        else
4827
          program_interrupt(processor, cia,
4828
                            illegal_instruction_program_interrupt);
4829
 
4830
 
4831
#
4832
# III.2.3.1 System Linkage Instructions
4833
#
4834
 
4835
0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4836
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4837
*603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4838
*603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4839
*604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
4840
        if (IS_PROBLEM_STATE(processor)) {
4841
          program_interrupt(processor, cia,
4842
                            privileged_instruction_program_interrupt);
4843
        }
4844
        else {
4845
          MSR = (MASKED(SRR1, 0, 32)
4846
                 | MASKED(SRR1, 37, 41)
4847
                 | MASKED(SRR1, 48, 63));
4848
          NIA = MASKED(SRR0, 0, 61);
4849
          cpu_synchronize_context(processor, cia);
4850
          check_masked_interrupts(processor);
4851
        }
4852
 
4853
#
4854
# III.3.4.1 Move to/from System Register Instructions
4855
#
4856
 
4857
#0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4858
#0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4859
0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4860
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4861
*603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4862
*603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4863
*604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4864
        if (IS_PROBLEM_STATE(processor))
4865
          program_interrupt(processor, cia,
4866
                            privileged_instruction_program_interrupt);
4867
        else {
4868
          MSR = *rS;
4869
          check_masked_interrupts(processor);
4870
        }
4871
 
4872
0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4873
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4874
*603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4875
*603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
4876
*604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
4877
        if (IS_PROBLEM_STATE(processor))
4878
          program_interrupt(processor, cia,
4879
                            privileged_instruction_program_interrupt);
4880
        else {
4881
          *rT = MSR;
4882
          check_masked_interrupts(processor);
4883
        }
4884
 
4885
 
4886
#
4887
# III.4.11.1 Cache Management Instructions
4888
#
4889
 
4890
0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4891
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4892
*603: PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4893
*603e:PPC_UNIT_LSU,   PPC_UNIT_LSU,   2,  2,  0
4894
*604: PPC_UNIT_LSU,   PPC_UNIT_LSU,   1,  3,  0
4895
        if (IS_PROBLEM_STATE(processor))
4896
          program_interrupt(processor, cia,
4897
                            privileged_instruction_program_interrupt);
4898
        else
4899
          TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4900
 
4901
#
4902
# III.4.11.2 Segment Register Manipulation Instructions
4903
#
4904
 
4905
0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4906
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4907
*603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4908
*603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4909
*604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4910
        if (IS_PROBLEM_STATE(processor))
4911
          program_interrupt(processor, cia,
4912
                            privileged_instruction_program_interrupt);
4913
        else
4914
          SEGREG(SR) = *rS;
4915
 
4916
0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4917
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
4918
*603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4919
*603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
4920
*604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4921
        if (IS_PROBLEM_STATE(processor))
4922
          program_interrupt(processor, cia,
4923
                            privileged_instruction_program_interrupt);
4924
        else
4925
          SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4926
 
4927
0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4928
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
4929
*603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4930
*603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4931
*604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4932
        if (IS_PROBLEM_STATE(processor))
4933
          program_interrupt(processor, cia,
4934
                            privileged_instruction_program_interrupt);
4935
        else
4936
          *rT = SEGREG(SR);
4937
 
4938
0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4939
*601: PPC_UNIT_IU,    PPC_UNIT_IU,    2,  2,  0
4940
*603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4941
*603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   3,  3,  0
4942
*604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
4943
        if (IS_PROBLEM_STATE(processor))
4944
          program_interrupt(processor, cia,
4945
                            privileged_instruction_program_interrupt);
4946
        else
4947
          *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4948
 
4949
 
4950
#
4951
# III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4952
#
4953
 
4954
0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4955
 
4956
0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4957
 
4958
0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4959
        if (IS_PROBLEM_STATE(processor))
4960
          program_interrupt(processor, cia,
4961
                            privileged_instruction_program_interrupt);
4962
        else {
4963
          int nr = 0;
4964
          cpu *proc;
4965
          while (1) {
4966
            proc = psim_cpu(cpu_system(processor), nr);
4967
            if (proc == NULL) break;
4968
            cpu_page_tlb_invalidate_entry(proc, *rB);
4969
            nr++;
4970
          }
4971
        }
4972
 
4973
0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4974
        if (IS_PROBLEM_STATE(processor))
4975
          program_interrupt(processor, cia,
4976
                            privileged_instruction_program_interrupt);
4977
        else {
4978
          int nr = 0;
4979
          cpu *proc;
4980
          while (1) {
4981
            proc = psim_cpu(cpu_system(processor), nr);
4982
            if (proc == NULL) break;
4983
            cpu_page_tlb_invalidate_all(proc);
4984
            nr++;
4985
          }
4986
        }
4987
 
4988
0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
4989
        /* nothing happens here - always in sync */
4990
 
4991
#
4992
# III.A.1.2 External Access Instructions
4993
#
4994
 
4995
0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4996
 
4997
0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
4998
 
4999
:include:::altivec.igen
5000
:include:::e500.igen

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.