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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [sim/] [ppc/] [ppc-instructions] - Blame information for rev 1780

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

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

powered by: WebSVN 2.1.0

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