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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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