2 # This file is part of the program psim.
4 # Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney
8 # The pseudo-code that appears below, translated into C, was copied
9 # by Andrew Cagney of Moss Vale, Australia.
11 # This pseudo-code is copied by permission from the publication
12 # "The PowerPC Architecture: A Specification for A New Family of
13 # RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by
14 # International Business Machines Corporation.
16 # THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER
17 # EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES
18 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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.
27 # This program is distributed in the hope that it will be useful,
28 # but WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 # GNU General Public License for more details.
32 # You should have received a copy of the GNU General Public License
33 # along with this program; if not, write to the Free Software
34 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 :cache:::signed_word *:rA:RA:(cpu_registers(processor)->gpr + RA)
39 :cache:::unsigned32:RA_BITMASK:RA:(1 << RA)
40 :compute:::int:RA_is_0:RA:(RA == 0)
42 :cache:::signed_word *:rT:RT:(cpu_registers(processor)->gpr + RT)
43 :cache:::unsigned32:RT_BITMASK:RT:(1 << RT)
45 :cache:::signed_word *:rS:RS:(cpu_registers(processor)->gpr + RS)
46 :cache:::unsigned32:RS_BITMASK:RS:(1 << RS)
48 :cache:::signed_word *:rB:RB:(cpu_registers(processor)->gpr + RB)
49 :cache:::unsigned32:RB_BITMASK:RB:(1 << RB)
51 :cache:::unsigned64 *:frA:FRA:(cpu_registers(processor)->fpr + FRA)
52 :cache:::unsigned32:FRA_BITMASK:FRA:(1 << FRA)
54 :cache:::unsigned64 *:frB:FRB:(cpu_registers(processor)->fpr + FRB)
55 :cache:::unsigned32:FRB_BITMASK:FRB:(1 << FRB)
57 :cache:::unsigned64 *:frC:FRC:(cpu_registers(processor)->fpr + FRC)
58 :cache:::unsigned32:FRC_BITMASK:FRC:(1 << FRC)
60 :cache:::unsigned64 *:frS:FRS:(cpu_registers(processor)->fpr + FRS)
61 :cache:::unsigned32:FRS_BITMASK:FRS:(1 << FRS)
63 :cache:::unsigned64 *:frT:FRT:(cpu_registers(processor)->fpr + FRT)
64 :cache:::unsigned32:FRT_BITMASK:FRT:(1 << FRT)
65 :cache:::unsigned_word:EXTS_SI:SI:((signed_word)(signed16)instruction)
67 :cache::::BIT32_BI:BI:BIT32(BI)
69 :cache:::unsigned32:BF_BITMASK:BF:(1 << BF)
71 :cache::::BIT32_BA:BA:BIT32(BA)
72 :cache:::unsigned32:BA_BITMASK:BA:(1 << BA)
74 :cache::::BIT32_BB:BB:BIT32(BB)
75 :cache:::unsigned32:BB_BITMASK:BB:(1 << BB)
77 :cache:::unsigned32:BT_BITMASK:BT:(1 << BT)
78 :cache:::unsigned_word:EXTS_BD_0b00:BD:(((signed_word)(signed16)instruction) & ~3)
79 :cache:::unsigned_word:EXTS_LI_0b00:LI:((((signed_word)(signed32)(instruction << 6)) >> 6) & ~0x3)
80 :cache:::unsigned_word:EXTS_D:D:((signed_word)(signed16)(instruction))
81 :cache:::unsigned_word:EXTS_DS_0b00:DS:(((signed_word)(signed16)instruction) & ~0x3)
82 #:compute:::int:SPR_is_256:SPR:(SPR == 256)
85 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
86 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
87 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
88 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
92 #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \
94 if (CURRENT_MODEL_ISSUE > 0) { \
96 ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
98 ppc_insn_int(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
102 #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \
104 if (CURRENT_MODEL_ISSUE > 0) \
105 ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
108 #define PPC_INSN_CR(OUT_MASK, IN_MASK) \
110 if (CURRENT_MODEL_ISSUE > 0) \
111 ppc_insn_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
114 #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \
116 if (CURRENT_MODEL_ISSUE > 0) { \
118 ppc_insn_float(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
120 ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
124 #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \
126 if (CURRENT_MODEL_ISSUE > 0) \
127 ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
130 #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \
132 if (CURRENT_MODEL_ISSUE > 0) \
133 ppc_insn_int_float(MY_INDEX, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \
136 #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \
138 if (CURRENT_MODEL_ISSUE > 0) \
139 ppc_insn_from_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
142 #define PPC_INSN_TO_SPR(INT_MASK, SPR) \
144 if (CURRENT_MODEL_ISSUE > 0) \
145 ppc_insn_to_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
148 #define PPC_INSN_MFCR(INT_MASK) \
150 if (CURRENT_MODEL_ISSUE > 0) \
151 ppc_insn_mfcr(MY_INDEX, cpu_model(processor), INT_MASK); \
154 #define PPC_INSN_MTCR(INT_MASK, FXM) \
156 if (CURRENT_MODEL_ISSUE > 0) \
157 ppc_insn_mtcr(MY_INDEX, cpu_model(processor), INT_MASK, FXM); \
161 typedef enum _ppc_function_unit {
162 PPC_UNIT_BAD, /* unknown function unit */
163 PPC_UNIT_IU, /* integer unit (601/603 style) */
164 PPC_UNIT_SRU, /* system register unit (601/603 style) */
165 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
166 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
167 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
168 PPC_UNIT_FPU, /* floating point unit */
169 PPC_UNIT_LSU, /* load/store unit */
170 PPC_UNIT_BPU, /* branch unit */
171 nr_ppc_function_units
174 /* Structure to hold timing information on a per instruction basis */
176 ppc_function_unit first_unit; /* first functional unit this insn could use */
177 ppc_function_unit second_unit; /* second functional unit this insn could use */
178 signed16 issue; /* # cycles before function unit can process other insns */
179 signed16 done; /* # cycles before insn is done */
180 unsigned32 flags; /* any flags that are needed */
183 /* Register mappings in status masks */
184 #define PPC_CR_REG 0 /* start of CR0 .. CR7 */
185 #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */
187 #define PPC_NO_SPR (-1) /* flag for no SPR register */
189 /* Return if 1 bit set */
190 #define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0)
192 /* Structure for each functional unit that is busy */
193 typedef struct _model_busy model_busy;
195 model_busy *next; /* next function unit */
196 ppc_function_unit unit; /* function unit name */
197 unsigned32 int_busy; /* int registers that are busy */
198 unsigned32 fp_busy; /* floating point registers that are busy */
199 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
200 signed16 spr_busy; /* SPR register that is busy or PPC_NO_SPR */
201 signed16 issue; /* # of cycles until unit can accept another insn */
202 signed16 done; /* # of cycles until insn is done */
203 signed16 nr_writebacks; /* # of registers this unit writes back */
206 /* Structure to hold the current state information for the simulated CPU model */
208 cpu *processor; /* point back to processor */
209 const char *name; /* model name */
210 const model_time *timing; /* timing information */
211 model_busy busy_head; /* dummy entry to head list of busy function units */
212 model_busy *busy_tail; /* tail of list of busy function units */
213 model_busy *free_list; /* list of model_busy structs not in use */
214 count_type nr_cycles; /* # cycles */
215 count_type nr_branches; /* # branches */
216 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
217 count_type nr_branch_predict_trues; /* # branches predicted correctly */
218 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
219 count_type nr_branch_conditional[32]; /* # of each type of bc */
220 count_type nr_mtcrf_crs[9]; /* # of CR's moved in a mtcrf instruction */
221 count_type nr_stalls_data; /* # of stalls for data */
222 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
223 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
224 count_type nr_stalls_writeback; /* # of stalls waiting for a writeback slot */
225 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
226 int max_nr_writebacks; /* max # of writeback slots available */
227 unsigned32 int_busy; /* int registers that are busy */
228 unsigned32 fp_busy; /* floating point registers that are busy */
229 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
230 unsigned8 spr_busy[nr_of_sprs]; /* SPR registers that are busy */
231 unsigned8 busy[nr_ppc_function_units]; /* whether a function is busy or not */
234 static const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
235 "unknown functional unit instruction",
236 "integer functional unit instruction",
237 "system register functional unit instruction",
238 "1st single cycle integer functional unit instruction",
239 "2nd single cycle integer functional unit instruction",
240 "multiple cycle integer functional unit instruction",
241 "floating point functional unit instruction",
242 "load/store functional unit instruction",
243 "branch functional unit instruction",
246 static const char *const ppc_branch_conditional_name[32] = {
247 "branch if --CTR != 0 and condition is FALSE", /* 0000y */
248 "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
249 "branch if --CTR == 0 and condition is FALSE", /* 0001y */
250 "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
251 "branch if the condition is FALSE", /* 001zy */
252 "branch if the condition is FALSE, reverse branch likely",
253 "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */
254 "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
255 "branch if --CTR != 0 and condition is TRUE", /* 0100y */
256 "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
257 "branch if --CTR == 0 and condition is TRUE", /* 0101y */
258 "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
259 "branch if the condition is TRUE", /* 011zy */
260 "branch if the condition is TRUE, reverse branch likely",
261 "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */
262 "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
263 "branch if --CTR != 0", /* 1z00y */
264 "branch if --CTR != 0, reverse branch likely",
265 "branch if --CTR == 0", /* 1z01y */
266 "branch if --CTR == 0, reverse branch likely",
267 "branch always", /* 1z1zz */
268 "branch always (ignored bit 5 set to 1)",
269 "branch always (ignored bit 4 set to 1)", /* 1z1zz */
270 "branch always (ignored bits 4,5 set to 1)",
271 "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */
272 "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
273 "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */
274 "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
275 "branch always (ignored bit 1 set to 1)", /* 1z1zz */
276 "branch always (ignored bits 1,5 set to 1)",
277 "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */
278 "branch always (ignored bits 1,4,5 set to 1)",
281 static const char *const ppc_nr_mtcrf_crs[9] = {
282 "mtcrf moving 0 CRs",
284 "mtcrf moving 2 CRs",
285 "mtcrf moving 3 CRs",
286 "mtcrf moving 4 CRs",
287 "mtcrf moving 5 CRs",
288 "mtcrf moving 6 CRs",
289 "mtcrf moving 7 CRs",
290 "mtcrf moving all CRs",
293 # Trace releasing resources
294 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
296 TRACE(trace_model,("done, %s, %d writeback%s\n", ppc_function_unit_name[busy->unit],
297 busy->nr_writebacks, busy->nr_writebacks == 1 ? "" : "s"));
298 if (busy->int_busy) {
299 for(i = 0; i < 32; i++) {
300 if (((1 << i) & busy->int_busy) != 0) {
301 TRACE(trace_model, ("Register r%d is now available.\n", i));
306 for(i = 0; i < 32; i++) {
307 if (((1 << i) & busy->fp_busy) != 0) {
308 TRACE(trace_model, ("Register f%d is now available.\n", i));
312 if (busy->cr_fpscr_busy) {
313 for(i = 0; i < 8; i++) {
314 if (((1 << i) & busy->cr_fpscr_busy) != 0) {
315 TRACE(trace_model, ("Register cr%d is now available.\n", i));
318 if (busy->cr_fpscr_busy & 0x100)
319 TRACE(trace_model, ("Register fpscr is now available.\n"));
321 if (busy->spr_busy != PPC_NO_SPR)
322 TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
324 # Trace making registers busy
325 void::model-static::model_trace_make_busy:model_data *model_ptr, unsigned32 int_mask, unsigned32 fp_mask, unsigned32 cr_mask
328 for(i = 0; i < 32; i++) {
329 if (((1 << i) & int_mask) != 0) {
330 TRACE(trace_model, ("Register r%d is now busy.\n", i));
335 for(i = 0; i < 32; i++) {
336 if (((1 << i) & fp_mask) != 0) {
337 TRACE(trace_model, ("Register f%d is now busy.\n", i));
342 for(i = 0; i < 8; i++) {
343 if (((1 << i) & cr_mask) != 0) {
344 TRACE(trace_model, ("Register cr%d is now busy.\n", i));
349 # Trace waiting for registers to become available
350 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
353 int_busy &= model_ptr->int_busy;
354 for(i = 0; i < 32; i++) {
355 if (((1 << i) & int_busy) != 0) {
356 TRACE(trace_model, ("Waiting for register r%d.\n", i));
361 fp_busy &= model_ptr->fp_busy;
362 for(i = 0; i < 32; i++) {
363 if (((1 << i) & fp_busy) != 0) {
364 TRACE(trace_model, ("Waiting for register f%d.\n", i));
368 if (cr_or_fpscr_busy) {
369 cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
370 for(i = 0; i < 8; i++) {
371 if (((1 << i) & cr_or_fpscr_busy) != 0) {
372 TRACE(trace_model, ("Waiting for register cr%d.\n", i));
375 if (cr_or_fpscr_busy & 0x100)
376 TRACE(trace_model, ("Waiting for register fpscr.\n"));
378 if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
379 TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
381 # Advance state to next cycle, releasing any registers allocated
382 void::model-internal::model_new_cycle:model_data *model_ptr
383 model_busy *cur_busy = model_ptr->busy_head.next;
384 model_busy *free_list = model_ptr->free_list;
385 model_busy *busy_tail = &model_ptr->busy_head;
386 int nr_writebacks = model_ptr->max_nr_writebacks;
389 model_ptr->nr_cycles++;
390 TRACE(trace_model,("New cycle %lu\n", (unsigned long)model_ptr->nr_cycles));
391 for ( ; cur_busy; cur_busy = next) {
392 next = cur_busy->next;
393 if (--cur_busy->done <= 0) { /* function unit done, release registers if we have writeback slots */
394 nr_writebacks -= cur_busy->nr_writebacks;
395 if (nr_writebacks >= 0) {
396 model_ptr->int_busy &= ~cur_busy->int_busy;
397 model_ptr->fp_busy &= ~cur_busy->fp_busy;
398 model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
399 if (cur_busy->spr_busy != PPC_NO_SPR)
400 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
402 if (WITH_TRACE && ppc_trace[trace_model])
403 model_trace_release(model_ptr, cur_busy);
405 model_ptr->busy[cur_busy->unit] = 0;
406 cur_busy->next = free_list;
407 free_list = cur_busy;
409 else { /* writeback slots not available */
410 TRACE(trace_model,("%d writeback slot%s not available for %s\n",
411 cur_busy->nr_writebacks,
412 cur_busy->nr_writebacks == 1 ? " is" : "s are",
413 ppc_function_unit_name[cur_busy->unit]));
414 cur_busy->done++; /* undo -- above */
415 model_ptr->nr_stalls_writeback++;
416 busy_tail->next = cur_busy;
417 busy_tail = cur_busy;
420 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
421 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
422 model_ptr->busy[cur_busy->unit] = 0;
423 busy_tail->next = cur_busy;
424 busy_tail = cur_busy;
427 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
428 ppc_function_unit_name[cur_busy->unit],
431 busy_tail->next = cur_busy;
432 busy_tail = cur_busy;
436 busy_tail->next = (model_busy *)0;
437 model_ptr->busy_tail = busy_tail;
438 model_ptr->free_list = free_list;
440 # Mark a function unit as busy, return the busy structure
441 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
444 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
446 if (!model_ptr->free_list) {
447 busy = ZALLOC(model_busy);
450 busy = model_ptr->free_list;
451 model_ptr->free_list = busy->next;
452 busy->next = (model_busy *)0;
455 busy->cr_fpscr_busy = 0;
456 busy->nr_writebacks = 0;
462 busy->spr_busy = PPC_NO_SPR;
463 model_ptr->busy_tail->next = busy;
464 model_ptr->busy_tail = busy;
465 model_ptr->busy[unit] = 1;
466 model_ptr->nr_units[unit]++;
469 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
470 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
471 ppc_function_unit first_unit = time_ptr->first_unit;
472 ppc_function_unit second_unit = time_ptr->second_unit;
473 int stall_increment = 0;
476 if (!model_ptr->busy[first_unit])
477 return model_make_busy(model_ptr, first_unit,
478 model_ptr->timing[index].issue,
479 model_ptr->timing[index].done);
481 if (!model_ptr->busy[second_unit])
482 return model_make_busy(model_ptr, second_unit,
483 model_ptr->timing[index].issue,
484 model_ptr->timing[index].done);
486 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
487 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
489 model_new_cycle(model_ptr);
492 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
493 void::model-function::model_serialize:itable_index index, model_data *model_ptr
494 while (model_ptr->busy_head.next) {
495 TRACE(trace_model,("waiting for pipeline to empty\n"));
496 model_ptr->nr_stalls_serialize++;
497 model_new_cycle(model_ptr);
499 (void) model_make_busy(model_ptr,
500 model_ptr->timing[index].first_unit,
501 model_ptr->timing[index].issue,
502 model_ptr->timing[index].done);
504 # Wait for a CR to become unbusy
505 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
509 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
512 cr_mask = (1 << cr_var);
513 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
514 TRACE(trace_model,("waiting for CR %d\n", cr_var));
515 model_ptr->nr_stalls_data++;
516 model_new_cycle(model_ptr);
519 # Schedule an instruction that takes integer input registers and produces output registers
520 void::model-function::ppc_insn_int:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
521 const unsigned32 int_mask = out_mask | in_mask;
522 model_busy *busy_ptr;
524 if ((model_ptr->int_busy & int_mask) != 0) {
525 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
527 while ((model_ptr->int_busy & int_mask) != 0) {
528 if (WITH_TRACE && ppc_trace[trace_model])
529 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
531 model_ptr->nr_stalls_data++;
532 model_new_cycle(model_ptr);
536 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
537 model_ptr->int_busy |= out_mask;
538 busy_ptr->int_busy |= out_mask;
540 busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
542 if (WITH_TRACE && ppc_trace[trace_model])
543 model_trace_make_busy(model_ptr, out_mask, 0, 0);
545 # Schedule an instruction that takes integer input registers and produces output registers & sets a CR register
546 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
547 const unsigned32 int_mask = out_mask | in_mask;
548 model_busy *busy_ptr;
550 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
551 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
553 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
554 if (WITH_TRACE && ppc_trace[trace_model])
555 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
557 model_ptr->nr_stalls_data++;
558 model_new_cycle(model_ptr);
562 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
563 model_ptr->int_busy |= out_mask;
564 busy_ptr->int_busy |= out_mask;
565 model_ptr->cr_fpscr_busy |= cr_mask;
566 busy_ptr->cr_fpscr_busy |= cr_mask;
568 busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
571 busy_ptr->nr_writebacks++;
573 if (WITH_TRACE && ppc_trace[trace_model])
574 model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
577 # Schedule an instruction that takes CR input registers and produces output CR registers
578 void::model-function::ppc_insn_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
579 const unsigned32 cr_mask = out_mask | in_mask;
580 model_busy *busy_ptr;
582 if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
583 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
585 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
586 if (WITH_TRACE && ppc_trace[trace_model])
587 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
589 model_ptr->nr_stalls_data++;
590 model_new_cycle(model_ptr);
594 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
595 model_ptr->cr_fpscr_busy |= out_mask;
596 busy_ptr->cr_fpscr_busy |= out_mask;
598 busy_ptr->nr_writebacks = 1;
600 if (WITH_TRACE && ppc_trace[trace_model])
601 model_trace_make_busy(model_ptr, 0, 0, out_mask);
604 # Schedule an instruction that takes floating point input registers and produces an output fp register
605 void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
606 const unsigned32 fp_mask = out_mask | in_mask;
607 model_busy *busy_ptr;
609 if ((model_ptr->fp_busy & fp_mask) != 0) {
610 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
612 while ((model_ptr->fp_busy & fp_mask) != 0) {
613 if (WITH_TRACE && ppc_trace[trace_model])
614 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
616 model_ptr->nr_stalls_data++;
617 model_new_cycle(model_ptr);
621 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
622 model_ptr->fp_busy |= out_mask;
623 busy_ptr->fp_busy |= out_mask;
624 busy_ptr->nr_writebacks = 1;
625 if (WITH_TRACE && ppc_trace[trace_model])
626 model_trace_make_busy(model_ptr, 0, out_mask, 0);
629 # Schedule an instruction that takes floating point input registers and produces an output fp register & sets a CR reg
630 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
631 const unsigned32 fp_mask = out_mask | in_mask;
632 model_busy *busy_ptr;
634 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
635 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
637 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
638 if (WITH_TRACE && ppc_trace[trace_model])
639 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
641 model_ptr->nr_stalls_data++;
642 model_new_cycle(model_ptr);
646 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
647 model_ptr->fp_busy |= out_mask;
648 busy_ptr->fp_busy |= out_mask;
649 model_ptr->cr_fpscr_busy |= cr_mask;
650 busy_ptr->cr_fpscr_busy |= cr_mask;
651 busy_ptr->nr_writebacks = (cr_mask) ? 2 : 1;
652 if (WITH_TRACE && ppc_trace[trace_model])
653 model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
656 # Schedule an instruction that takes both int/float input registers and produces output int/float registers
657 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
658 const unsigned32 int_mask = out_int_mask | in_int_mask;
659 const unsigned32 fp_mask = out_fp_mask | in_fp_mask;
660 model_busy *busy_ptr;
662 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
663 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
665 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
666 if (WITH_TRACE && ppc_trace[trace_model])
667 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
669 model_ptr->nr_stalls_data++;
670 model_new_cycle(model_ptr);
673 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
674 model_ptr->int_busy |= out_int_mask;
675 busy_ptr->int_busy |= out_int_mask;
676 model_ptr->fp_busy |= out_fp_mask;
677 busy_ptr->fp_busy |= out_fp_mask;
678 busy_ptr->nr_writebacks = ((out_int_mask) ? 1 : 0) + ((out_fp_mask) ? 1 : 0);
679 if (WITH_TRACE && ppc_trace[trace_model])
680 model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0);
684 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
685 void::model-function::ppc_insn_from_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
686 model_busy *busy_ptr;
688 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
689 if (WITH_TRACE && ppc_trace[trace_model])
690 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
692 model_ptr->nr_stalls_data++;
693 model_new_cycle(model_ptr);
696 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
697 model_ptr->int_busy |= int_mask;
698 busy_ptr->int_busy |= int_mask;
699 busy_ptr->nr_writebacks = 1;
700 if (WITH_TRACE && ppc_trace[trace_model])
701 model_trace_make_busy(model_ptr, int_mask, 0, 0);
703 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
704 void::model-function::ppc_insn_to_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
705 model_busy *busy_ptr;
707 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
708 if (WITH_TRACE && ppc_trace[trace_model])
709 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
711 model_ptr->nr_stalls_data++;
712 model_new_cycle(model_ptr);
715 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
716 busy_ptr->spr_busy = nSPR;
717 model_ptr->spr_busy[nSPR] = 1;
718 busy_ptr->nr_writebacks = 1;
719 TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));
721 # Schedule a MFCR instruction that moves the CR into an integer regsiter
722 void::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, unsigned32 int_mask
723 const unsigned32 cr_mask = 0xff;
724 model_busy *busy_ptr;
726 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
727 if (WITH_TRACE && ppc_trace[trace_model])
728 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
730 model_ptr->nr_stalls_data++;
731 model_new_cycle(model_ptr);
734 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
735 model_ptr->int_busy |= int_mask;
736 busy_ptr->int_busy |= int_mask;
737 busy_ptr->nr_writebacks = 1;
738 if (WITH_TRACE && ppc_trace[trace_model])
739 model_trace_make_busy(model_ptr, int_mask, 0, 0);
741 # Schedule a MTCR instruction that moves an integer register into the CR
742 void::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, unsigned32 int_mask, unsigned FXM
745 unsigned32 cr_mask = 0;
746 const model_time *normal_time = &model_ptr->timing[index];
747 static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 };
748 model_busy *busy_ptr;
750 for (f = 0; f < 8; f++) {
751 if (FXM & (0x80 >> f)) {
757 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
758 if (WITH_TRACE && ppc_trace[trace_model])
759 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
761 model_ptr->nr_stalls_data++;
762 model_new_cycle(model_ptr);
765 /* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */
766 if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) {
767 normal_time = &ppc604_1bit_time;
770 busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
771 busy_ptr->cr_fpscr_busy |= cr_mask;
772 model_ptr->cr_fpscr_busy |= cr_mask;
773 model_ptr->nr_mtcrf_crs[nr_crs]++;
774 busy_ptr->nr_writebacks = 1;
775 if (WITH_TRACE && ppc_trace[trace_model])
776 model_trace_make_busy(model_ptr, 0, 0, cr_mask);
778 model_data *::model-function::model_create:cpu *processor
779 model_data *model_ptr = ZALLOC(model_data);
780 model_ptr->name = model_name[CURRENT_MODEL];
781 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
782 model_ptr->processor = processor;
783 model_ptr->nr_cycles = 1;
784 model_ptr->busy_tail = &model_ptr->busy_head;
785 switch (CURRENT_MODEL) {
786 case MODEL_ppc601: model_ptr->max_nr_writebacks = 1; break; /* ??? */
787 case MODEL_ppc603: model_ptr->max_nr_writebacks = 2; break;
788 case MODEL_ppc603e: model_ptr->max_nr_writebacks = 2; break;
789 case MODEL_ppc604: model_ptr->max_nr_writebacks = 2; break;
790 default: error ("Unknown model %d\n", CURRENT_MODEL);
794 void::model-function::model_init:model_data *model_ptr
796 void::model-function::model_halt:model_data *model_ptr
797 /* Let pipeline drain */
798 while (model_ptr->busy_head.next)
799 model_new_cycle(model_ptr);
801 unsigned_word::model-function::model_get_number_of_stalls:model_data *model_ptr
802 return (model_ptr->nr_stalls_data
803 + model_ptr->nr_stalls_unit
804 + model_ptr->nr_stalls_serialize
805 + model_ptr->nr_stalls_writeback);
807 unsigned_word::model-function::model_get_number_of_cycles:model_data *model_ptr
808 return (model_ptr->nr_cycles);
810 model_print *::model-function::model_mon_info:model_data *model_ptr
817 head = tail = ZALLOC(model_print);
818 tail->count = model_ptr->nr_cycles;
819 tail->name = "cycle";
820 tail->suffix_plural = "s";
821 tail->suffix_singular = "";
823 if (model_ptr->nr_stalls_data) {
824 tail->next = ZALLOC(model_print);
826 tail->count = model_ptr->nr_stalls_data;
827 tail->name = "stall";
828 tail->suffix_plural = "s waiting for data";
829 tail->suffix_singular = " waiting for data";
832 if (model_ptr->nr_stalls_unit) {
833 tail->next = ZALLOC(model_print);
835 tail->count = model_ptr->nr_stalls_unit;
836 tail->name = "stall";
837 tail->suffix_plural = "s waiting for a function unit";
838 tail->suffix_singular = " waiting for a function unit";
841 if (model_ptr->nr_stalls_serialize) {
842 tail->next = ZALLOC(model_print);
844 tail->count = model_ptr->nr_stalls_serialize;
845 tail->name = "stall";
846 tail->suffix_plural = "s waiting for serialization";
847 tail->suffix_singular = " waiting for serialization";
850 if (model_ptr->nr_stalls_writeback) {
851 tail->next = ZALLOC(model_print);
853 tail->count = model_ptr->nr_stalls_writeback;
855 tail->suffix_plural = "times a write-back slot was unavailable";
856 tail->suffix_singular = "time a writeback was unavailable";
859 if (model_ptr->nr_branches) {
860 tail->next = ZALLOC(model_print);
862 tail->count = model_ptr->nr_branches;
863 tail->name = "branch";
864 tail->suffix_plural = "es";
865 tail->suffix_singular = "";
868 if (model_ptr->nr_branches_fallthrough) {
869 tail->next = ZALLOC(model_print);
871 tail->count = model_ptr->nr_branches_fallthrough;
872 tail->name = "conditional branch";
873 tail->suffix_plural = "es fell through";
874 tail->suffix_singular = " fell through";
877 if (model_ptr->nr_branch_predict_trues) {
878 tail->next = ZALLOC(model_print);
880 tail->count = model_ptr->nr_branch_predict_trues;
881 tail->name = "successful branch prediction";
882 tail->suffix_plural = "s";
883 tail->suffix_singular = "";
886 if (model_ptr->nr_branch_predict_falses) {
887 tail->next = ZALLOC(model_print);
889 tail->count = model_ptr->nr_branch_predict_falses;
890 tail->name = "unsuccessful branch prediction";
891 tail->suffix_plural = "s";
892 tail->suffix_singular = "";
895 for (j = 0; j < (sizeof(ppc_branch_conditional_name) / sizeof(ppc_branch_conditional_name[0])) ; j++) {
896 if (model_ptr->nr_branch_conditional[j]) {
897 tail->next = ZALLOC(model_print);
899 tail->count = model_ptr->nr_branch_conditional[j];
900 tail->name = ppc_branch_conditional_name[j];
901 tail->suffix_plural = " conditional branches";
902 tail->suffix_singular = " conditional branch";
906 for (j = 0; j < 9; j++) {
907 if (model_ptr->nr_mtcrf_crs[j]) {
908 tail->next = ZALLOC(model_print);
910 tail->count = model_ptr->nr_mtcrf_crs[j];
911 tail->name = ppc_nr_mtcrf_crs[j];
912 tail->suffix_plural = " instructions";
913 tail->suffix_singular = " instruction";
918 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
919 if (model_ptr->nr_units[i]) {
920 nr_insns += model_ptr->nr_units[i];
921 tail->next = ZALLOC(model_print);
923 tail->count = model_ptr->nr_units[i];
924 tail->name = ppc_function_unit_name[i];
925 tail->suffix_plural = "s";
926 tail->suffix_singular = "";
930 tail->next = ZALLOC(model_print);
932 tail->count = nr_insns;
933 tail->name = "instruction";
934 tail->suffix_plural = "s that were accounted for in timing info";
935 tail->suffix_singular = " that was accounted for in timing info";
937 tail->next = (model_print *)0;
940 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
942 model_print *next = ptr->next;
947 void::model-function::model_branches:model_data *model_ptr, int failed, int conditional
948 model_ptr->nr_units[PPC_UNIT_BPU]++;
950 model_ptr->nr_branches_fallthrough++;
952 model_ptr->nr_branches++;
953 if (conditional >= 0)
954 model_ptr->nr_branch_conditional[conditional]++;
955 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
957 void::model-function::model_branch_predict:model_data *model_ptr, int success
959 model_ptr->nr_branch_predict_trues++;
961 model_ptr->nr_branch_predict_falses++;
964 # The following (illegal) instruction is `known' by gen and is
965 # called when ever an illegal instruction is encountered
967 program_interrupt(processor, cia,
968 illegal_instruction_program_interrupt);
971 # The following (floating point unavailable) instruction is `known' by gen
972 # and is called when ever an a floating point instruction is to be
973 # executed but floating point is make unavailable by the MSR
974 ::internal::floating_point_unavailable
975 floating_point_unavailable_interrupt(processor, cia);
979 # Floating point support functions
982 # Convert 32bit single to 64bit double
983 unsigned64::function::DOUBLE:unsigned32 WORD
985 if (EXTRACTED32(WORD, 1, 8) > 0
986 && EXTRACTED32(WORD, 1, 8) < 255) {
987 /* normalized operand */
988 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
989 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
990 | INSERTED64(not_word_1_1, 2, 2)
991 | INSERTED64(not_word_1_1, 3, 3)
992 | INSERTED64(not_word_1_1, 4, 4)
993 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
995 else if (EXTRACTED32(WORD, 1, 8) == 0
996 && EXTRACTED32(WORD, 9, 31) != 0) {
997 /* denormalized operand */
998 int sign = EXTRACTED32(WORD, 0, 0);
1000 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
1001 /* normalize the operand */
1002 while (MASKED64(frac, 0, 0) == 0) {
1006 FRT = (INSERTED64(sign, 0, 0)
1007 | INSERTED64(exp + 1023, 1, 11)
1008 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
1010 else if (EXTRACTED32(WORD, 1, 8) == 255
1011 || EXTRACTED32(WORD, 1, 31) == 0) {
1012 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
1013 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
1014 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
1015 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
1016 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
1019 error("DOUBLE - unknown case\n");
1024 # Convert 64bit single to 32bit double
1025 unsigned32::function::SINGLE:unsigned64 FRS
1027 if (EXTRACTED64(FRS, 1, 11) > 896
1028 || EXTRACTED64(FRS, 1, 63) == 0) {
1029 /* no denormalization required (includes Zero/Infinity/NaN) */
1030 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
1031 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
1033 else if (874 <= EXTRACTED64(FRS, 1, 11)
1034 && EXTRACTED64(FRS, 1, 11) <= 896) {
1035 /* denormalization required */
1036 int sign = EXTRACTED64(FRS, 0, 0);
1037 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
1038 unsigned64 frac = (BIT64(0)
1039 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
1040 /* denormalize the operand */
1041 while (exp < -126) {
1042 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1045 WORD = (INSERTED32(sign, 0, 0)
1046 | INSERTED32(0x00, 1, 8)
1047 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
1050 WORD = 0x0; /* ??? */
1055 # round 64bit double to 64bit but single
1056 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
1057 /* comparisons ignore u bits */
1060 int lsb = EXTRACTED64(*frac_grx, 23, 23);
1061 int gbit = EXTRACTED64(*frac_grx, 24, 24);
1062 int rbit = EXTRACTED64(*frac_grx, 25, 25);
1063 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
1064 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
1065 if (lsb == 1 && gbit == 1) inc = 1;
1066 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1067 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1069 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
1070 if (sign == 0 && gbit == 1) inc = 1;
1071 if (sign == 0 && rbit == 1) inc = 1;
1072 if (sign == 0 && xbit == 1) inc = 1;
1074 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
1075 if (sign == 1 && gbit == 1) inc = 1;
1076 if (sign == 1 && rbit == 1) inc = 1;
1077 if (sign == 1 && xbit == 1) inc = 1;
1079 /* work out addition in low 25 bits of out */
1080 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
1081 *frac_grx = INSERTED64(out, 0, 23);
1082 if (out & BIT64(64 - 23 - 1 - 1)) {
1083 *frac_grx = (BIT64(0) |
1084 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
1087 /* frac_grx[24:52] = 0 already */
1089 FPSCR_SET_FI(gbit || rbit || xbit);
1093 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
1095 if (round_mode == fpscr_rn_round_to_nearest) {
1096 if (*frac64 == 1 && gbit == 1) inc = 1;
1097 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
1098 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
1100 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1101 if (sign == 0 && gbit == 1) inc = 1;
1102 if (sign == 0 && rbit == 1) inc = 1;
1103 if (sign == 0 && xbit == 1) inc = 1;
1105 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1106 if (sign == 1 && gbit == 1) inc = 1;
1107 if (sign == 1 && rbit == 1) inc = 1;
1108 if (sign == 1 && xbit == 1) inc = 1;
1110 /* frac[0:64] = frac[0:64} + inc */
1111 *frac += (*frac64 && inc ? 1 : 0);
1112 *frac64 = (*frac64 + inc) & 0x1;
1114 FPSCR_SET_FI(gbit | rbit | xbit);
1117 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
1120 int lsb = EXTRACTED64(*frac, 52, 52);
1121 int gbit = EXTRACTED64(*frac, 53, 53);
1122 int rbit = EXTRACTED64(*frac, 54, 54);
1123 int xbit = EXTRACTED64(*frac, 55, 55);
1124 if (round_mode == fpscr_rn_round_to_nearest) {
1125 if (lsb == 1 && gbit == 1) inc = 1;
1126 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1127 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1129 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1130 if (sign == 0 && gbit == 1) inc = 1;
1131 if (sign == 0 && rbit == 1) inc = 1;
1132 if (sign == 0 && xbit == 1) inc = 1;
1134 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1135 if (sign == 1 && gbit == 1) inc = 1;
1136 if (sign == 1 && rbit == 1) inc = 1;
1137 if (sign == 1 && xbit == 1) inc = 1;
1139 /* frac//carry_out = frac + inc */
1140 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1141 carry_out = EXTRACTED64(*frac, 0, 0);
1143 if (carry_out == 1) *exp = *exp + 1;
1145 FPSCR_SET_FI(gbit | rbit | xbit);
1146 FPSCR_SET_XX(FPSCR & fpscr_fi);
1149 # conversion of FP to integer
1150 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
1153 unsigned64 frac = 0;
1158 int sign = EXTRACTED64(frb, 0, 0);
1160 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1161 GOTO(Infinity_Operand);
1162 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1164 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1166 if (EXTRACTED64(frb, 1, 11) > 1086) GOTO(Large_Operand);
1167 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1168 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1169 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1170 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1173 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1174 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1177 gbit = 0, rbit = 0, xbit = 0;
1178 for (i = 1; i <= 63 - exp; i++) {
1182 frac64 = EXTRACTED64(frac, 63, 63);
1183 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1185 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1186 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1189 frac += (frac64 ? 1 : 0);
1190 frac64 = (frac64 + 1) & 0x1;
1192 if (tgt_precision == 32 /* can ignore frac64 in compare */
1193 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1194 GOTO(Large_Operand);
1195 if (tgt_precision == 64 /* can ignore frac64 in compare */
1196 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1197 GOTO(Large_Operand);
1198 if (tgt_precision == 32 /* can ignore frac64 in compare */
1199 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1200 GOTO(Large_Operand);
1201 if (tgt_precision == 64 /* can ignore frac64 in compare */
1202 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1203 GOTO(Large_Operand);
1204 FPSCR_SET_XX(FPSCR & fpscr_fi);
1205 if (tgt_precision == 32)
1206 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1207 if (tgt_precision == 64)
1208 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1209 /*FPSCR[fprf] = undefined */
1212 LABEL(Infinity_Operand):
1215 FPSCR_OR_VX(fpscr_vxcvi);
1216 if ((FPSCR & fpscr_ve) == 0) {
1217 if (tgt_precision == 32) {
1218 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1219 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1222 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1223 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1225 /* FPSCR[FPRF] = undefined */
1229 LABEL(SNaN_Operand):
1232 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1233 if ((FPSCR & fpscr_ve) == 0) {
1234 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1235 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1236 /* FPSCR[fprf] = undefined */
1240 LABEL(QNaN_Operand):
1243 FPSCR_OR_VX(fpscr_vxcvi);
1244 if ((FPSCR & fpscr_ve) == 0) {
1245 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1246 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1247 /* FPSCR[fprf] = undefined */
1251 LABEL(Large_Operand):
1254 FPSCR_OR_VX(fpscr_vxcvi);
1255 if ((FPSCR & fpscr_ve) == 0) {
1256 if (tgt_precision == 32) {
1257 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1258 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1261 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1262 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1264 /* FPSCR[fprf] = undefined */
1270 # extract out raw fields of a FP number
1271 int::function::sign:unsigned64 FRS
1272 return (MASKED64(FRS, 0, 0)
1275 int::function::biased_exp:unsigned64 frs, int single
1277 return EXTRACTED64(frs, 1, 8);
1279 return EXTRACTED64(frs, 1, 11);
1280 unsigned64::function::fraction:unsigned64 frs, int single
1282 return EXTRACTED64(frs, 9, 31);
1284 return EXTRACTED64(frs, 12, 63);
1286 # a number?, each of the below return +1 or -1 (based on sign bit)
1288 int::function::is_nor:unsigned64 frs, int single
1289 int exp = biased_exp(frs, single);
1291 && exp <= (single ? 254 : 2046));
1292 int::function::is_zero:unsigned64 FRS
1293 return (MASKED64(FRS, 1, 63) == 0
1296 int::function::is_den:unsigned64 frs, int single
1297 int exp = biased_exp(frs, single);
1298 unsigned64 frac = fraction(frs, single);
1299 return (exp == 0 && frac != 0
1302 int::function::is_inf:unsigned64 frs, int single
1303 int exp = biased_exp(frs, single);
1304 unsigned64 frac = fraction(frs, single);
1305 return (exp == (single ? 255 : 2047) && frac == 0
1308 int::function::is_NaN:unsigned64 frs, int single
1309 int exp = biased_exp(frs, single);
1310 unsigned64 frac = fraction(frs, single);
1311 return (exp == (single ? 255 : 2047) && frac != 0
1314 int::function::is_SNaN:unsigned64 frs, int single
1315 return (is_NaN(frs, single)
1316 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1319 int::function::is_QNaN:unsigned64 frs, int single
1320 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1321 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1322 return *(double*)fra < *(double*)frb;
1323 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1324 return *(double*)fra > *(double*)frb;
1325 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1326 return *(double*)fra == *(double*)frb;
1329 # which quiet nan should become the result
1330 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1332 if (is_NaN(fra, single))
1334 else if (is_NaN(frb, single))
1335 if (instruction_is_frsp)
1336 frt = MASKED64(frb, 0, 34);
1339 else if (is_NaN(frc, single))
1341 else if (generate_qnan)
1342 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1344 error("select_qnan - default reached\n");
1348 # detect invalid operation
1349 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1351 if ((check & fpscr_vxsnan)
1352 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1353 FPSCR_OR_VX(fpscr_vxsnan);
1356 if ((check & fpscr_vxisi)
1357 && (is_inf(fra, single) && is_inf(frb, single))
1358 && ((negate && sign(fra) != sign(frb))
1359 || (!negate && sign(fra) == sign(frb)))) {
1360 /*FIXME: don't handle inf-inf VS inf+-inf */
1361 FPSCR_OR_VX(fpscr_vxisi);
1364 if ((check & fpscr_vxidi)
1365 && (is_inf(fra, single) && is_inf(frb, single))) {
1366 FPSCR_OR_VX(fpscr_vxidi);
1369 if ((check & fpscr_vxzdz)
1370 && (is_zero(fra) && is_zero(frb))) {
1371 FPSCR_OR_VX(fpscr_vxzdz);
1374 if ((check & fpscr_vximz)
1375 && (is_zero(fra) && is_inf(frb, single))) {
1376 FPSCR_OR_VX(fpscr_vximz);
1379 if ((check & fpscr_vxvc)
1380 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1381 FPSCR_OR_VX(fpscr_vxvc);
1384 if ((check & fpscr_vxsoft)) {
1385 FPSCR_OR_VX(fpscr_vxsoft);
1388 if ((check & fpscr_vxsqrt)
1390 FPSCR_OR_VX(fpscr_vxsqrt);
1393 /* if ((check && fpscr_vxcvi) {
1394 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1395 FPSCR_OR_VX(fpscr_vxcvi);
1405 # handle case of invalid operation
1406 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
1407 if (FPSCR & fpscr_ve) {
1408 /* invalid operation exception enabled */
1412 /* fpscr_FPRF unchanged */
1415 /* invalid operation exception disabled */
1416 if (instruction_is_convert_to_64bit) {
1419 else if (instruction_is_convert_to_32bit) {
1422 else { /* arrith, frsp */
1423 *frt = select_qnan(fra, frb, frc,
1424 instruction_is_frsp, 1/*generate*/, single);
1427 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1434 # detect divide by zero
1435 int::function::is_invalid_zero_divide:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, int single
1437 if (is_zero (frb)) {
1446 # handle case of invalid operation
1447 void::function::invalid_zero_divide_operation:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 fra, unsigned64 frb, int single
1448 if (FPSCR & fpscr_ze) {
1449 /* zero-divide exception enabled */
1453 /* fpscr_FPRF unchanged */
1456 /* zero-divide exception disabled */
1459 if ((sign (fra) < 0 && sign (frb) < 0)
1460 || (sign (fra) > 0 && sign (frb) > 0)) {
1461 *frt = MASK64 (1, 11); /* 0 : 2047 : 0..0 */
1462 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
1465 *frt = MASK64 (0, 11); /* 1 : 2047 : 0..0 */
1466 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
1475 # 0.0.0.0 Illegal instruction used for kernel mode emulation
1477 0.0,6./,11./,16./,21./,31.1:X:::instruction_call
1478 if (!os_emul_instruction_call(processor, cia, real_addr(cia, 1)))
1479 program_interrupt(processor, cia,
1480 illegal_instruction_program_interrupt);
1483 # I.2.4.1 Branch Instructions
1485 0.18,6.LI,30.AA,31.LK:I:::Branch
1486 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1487 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1488 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1489 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1491 No problem here because this branch is predicted taken (unconditional). */
1492 if (AA) NIA = IEA(EXTS(LI_0b00));
1493 else NIA = IEA(CIA + EXTS(LI_0b00));
1494 if (LK) LR = (spreg)CIA+4;
1495 if (CURRENT_MODEL_ISSUE > 0)
1496 model_branches(cpu_model(processor), 1, -1);
1498 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:::Branch Conditional
1499 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1500 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1501 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1502 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1503 int M, ctr_ok, cond_ok, succeed;
1504 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1505 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1506 if (is_64bit_implementation && is_64bit_mode) M = 0;
1508 if (!BO{2}) CTR = CTR - 1;
1509 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1510 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1511 if (ctr_ok && cond_ok) {
1512 if (AA) NIA = IEA(EXTS(BD_0b00));
1513 else NIA = IEA(CIA + EXTS(BD_0b00));
1518 if (LK) LR = (spreg)IEA(CIA + 4);
1519 if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
1520 /* This branch is predicted as "normal".
1521 If this is a forward branch and it is near the end of a page,
1522 we've detected a problematic branch. */
1523 if (succeed && NIA > CIA) {
1524 if (PAGE_SIZE - (CIA & (PAGE_SIZE-1)) <= option_mpc860c0)
1525 program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt);
1528 if (CURRENT_MODEL_ISSUE > 0)
1529 model_branches(cpu_model(processor), succeed, BO);
1532 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1533 reverse = EXTS(BD_0b00) < 0;
1534 } else { /* branch prediction bit not set */
1535 reverse = EXTS(BD_0b00) >= 0;
1537 if (CURRENT_MODEL_ISSUE > 0)
1538 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1541 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:::Branch Conditional to Link Register
1542 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1543 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1544 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1545 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1546 int M, ctr_ok, cond_ok, succeed;
1547 if (is_64bit_implementation && is_64bit_mode) M = 0;
1549 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1550 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1551 if (!BO{2}) CTR = CTR - 1;
1552 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1553 cond_ok = BO{0} || (CR{BI} == BO{1});
1554 if (ctr_ok && cond_ok) {
1560 if (LK) LR = (spreg)IEA(CIA + 4);
1561 if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
1562 /* This branch is predicted as not-taken.
1563 If this is a forward branch and it is near the end of a page,
1564 we've detected a problematic branch. */
1565 if (succeed && NIA > CIA) {
1566 if (PAGE_SIZE - (CIA & (PAGE_SIZE-1)) <= option_mpc860c0)
1567 program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt);
1570 if (CURRENT_MODEL_ISSUE > 0) {
1571 model_branches(cpu_model(processor), succeed, BO);
1573 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1576 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:::Branch Conditional to Count Register
1577 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1578 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1579 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1580 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1581 int cond_ok, succeed;
1582 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1583 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1584 cond_ok = BO{0} || (CR{BI} == BO{1});
1586 NIA = IEA(CTR_0b00);
1591 if (LK) LR = (spreg)IEA(CIA + 4);
1592 if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
1593 /* This branch is predicted as not-taken.
1594 If this is a forward branch and it is near the end of a page,
1595 we've detected a problematic branch. */
1596 if (succeed && NIA > CIA) {
1597 if (PAGE_SIZE - (CIA & (PAGE_SIZE-1)) <= option_mpc860c0)
1598 program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt);
1601 if (CURRENT_MODEL_ISSUE > 0) {
1602 model_branches(cpu_model(processor), succeed, BO);
1604 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1608 # I.2.4.2 System Call Instruction
1610 0.17,6./,11./,16./,30.1,31./:SC:::System Call
1611 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1612 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1613 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1614 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1615 if (CURRENT_MODEL_ISSUE > 0)
1616 model_serialize(MY_INDEX, cpu_model(processor));
1617 system_call_interrupt(processor, cia);
1620 # I.2.4.3 Condition Register Logical Instructions
1622 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1623 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1624 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1625 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1626 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1627 BLIT32(CR, BT, CR{BA} && CR{BB});
1628 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1630 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1631 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1632 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1633 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1634 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1635 BLIT32(CR, BT, CR{BA} || CR{BB});
1636 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1638 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1639 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1640 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1641 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1642 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1643 BLIT32(CR, BT, CR{BA} != CR{BB});
1644 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1646 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1647 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1648 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1649 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1650 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1651 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1652 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1654 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1655 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1656 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1657 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1658 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1659 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1660 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1662 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1663 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1664 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1665 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1666 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1667 BLIT32(CR, BT, CR{BA} == CR{BB});
1668 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1670 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1671 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1672 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1673 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1674 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1675 BLIT32(CR, BT, CR{BA} && !CR{BB});
1676 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1678 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1679 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1680 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1681 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1682 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1683 BLIT32(CR, BT, CR{BA} || !CR{BB});
1684 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1687 # I.2.4.4 Condition Register Field Instruction
1689 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1690 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1691 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1692 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1693 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1694 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1695 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
1699 # I.3.3.2 Fixed-Point Load Instructions
1702 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1703 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1704 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1705 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1706 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1712 *rT = MEM(unsigned, EA, 1);
1713 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1716 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1717 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1718 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1719 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1720 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1726 *rT = MEM(unsigned, EA, 1);
1727 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1729 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1730 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1731 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1732 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1733 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1735 if (RA_is_0 || RA == RT)
1736 program_interrupt(processor, cia,
1737 illegal_instruction_program_interrupt);
1739 *rT = MEM(unsigned, EA, 1);
1741 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1743 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1744 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1745 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1746 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1747 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1749 if (RA_is_0 || RA == RT)
1750 program_interrupt(processor, cia,
1751 illegal_instruction_program_interrupt);
1753 *rT = MEM(unsigned, EA, 1);
1755 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1757 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1758 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1759 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1760 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1761 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1767 *rT = MEM(unsigned, EA, 2);
1768 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1770 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1771 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1772 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1773 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1774 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1780 *rT = MEM(unsigned, EA, 2);
1781 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1783 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1784 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1785 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1786 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1787 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1789 if (RA_is_0 || RA == RT)
1790 program_interrupt(processor, cia,
1791 illegal_instruction_program_interrupt);
1793 *rT = MEM(unsigned, EA, 2);
1795 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1797 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1798 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1799 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1800 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1801 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1803 if (RA_is_0 || RA == RT)
1804 program_interrupt(processor, cia,
1805 illegal_instruction_program_interrupt);
1807 *rT = MEM(unsigned, EA, 2);
1809 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1811 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1812 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1813 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1814 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1815 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1821 *rT = MEM(signed, EA, 2);
1822 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1824 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1825 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1826 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1827 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1828 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1834 *rT = MEM(signed, EA, 2);
1835 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1837 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1838 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1839 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1840 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1841 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1843 if (RA_is_0 || RA == RT)
1844 program_interrupt(processor, cia,
1845 illegal_instruction_program_interrupt);
1847 *rT = MEM(signed, EA, 2);
1849 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1851 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1852 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1853 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1854 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1855 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1857 if (RA_is_0 || RA == RT)
1858 program_interrupt(processor, cia,
1859 illegal_instruction_program_interrupt);
1861 *rT = MEM(signed, EA, 2);
1863 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1865 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1866 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1867 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1868 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1869 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1875 *rT = MEM(unsigned, EA, 4);
1876 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1878 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1879 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1880 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1881 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1882 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1888 *rT = MEM(unsigned, EA, 4);
1889 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1891 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1892 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1893 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1894 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1895 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1897 if (RA_is_0 || RA == RT)
1898 program_interrupt(processor, cia,
1899 illegal_instruction_program_interrupt);
1901 *rT = MEM(unsigned, EA, 4);
1903 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1905 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1906 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1907 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1908 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1909 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1911 if (RA_is_0 || RA == RT)
1912 program_interrupt(processor, cia,
1913 illegal_instruction_program_interrupt);
1915 *rT = MEM(unsigned, EA, 4);
1917 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1919 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1922 # if (RA_is_0) b = 0;
1924 # EA = b + EXTS(DS_0b00);
1925 # *rT = MEM(signed, EA, 4);
1927 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1930 # if (RA_is_0) b = 0;
1933 # *rT = MEM(signed, EA, 4);
1935 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1937 # if (RA_is_0 || RA == RT)
1938 # program_interrupt(processor, cia
1939 # illegal_instruction_program_interrupt);
1941 # *rT = MEM(signed, EA, 4);
1944 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1947 # if (RA_is_0) b = 0;
1949 # EA = b + EXTS(DS_0b00);
1950 # *rT = MEM(unsigned, EA, 8);
1952 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1955 # if (RA_is_0) b = 0;
1958 # *rT = MEM(unsigned, EA, 8);
1960 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1962 # if (RA_is_0 || RA == RT)
1963 # program_interrupt(processor, cia
1964 # illegal_instruction_program_interrupt);
1965 # EA = *rA + EXTS(DS_0b00);
1966 # *rT = MEM(unsigned, EA, 8);
1969 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1971 # if (RA_is_0 || RA == RT)
1972 # program_interrupt(processor, cia
1973 # illegal_instruction_program_interrupt);
1975 # *rT = MEM(unsigned, EA, 8);
1981 # I.3.3.3 Fixed-Point Store Instructions
1984 0.38,6.RS,11.RA,16.D:D:::Store Byte
1985 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1986 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1987 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1988 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1995 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1997 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1998 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1999 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2000 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2001 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2008 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2010 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
2011 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2012 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2013 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2014 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2017 program_interrupt(processor, cia,
2018 illegal_instruction_program_interrupt);
2022 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2024 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
2025 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2026 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2027 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2028 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2031 program_interrupt(processor, cia,
2032 illegal_instruction_program_interrupt);
2036 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2038 0.44,6.RS,11.RA,16.D:D:::Store Half Word
2039 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2040 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2041 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2042 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2049 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
2051 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
2052 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2053 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2054 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2055 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2062 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2064 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
2065 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2066 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2067 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2068 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2071 program_interrupt(processor, cia,
2072 illegal_instruction_program_interrupt);
2076 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2078 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
2079 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2080 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2081 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2082 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2085 program_interrupt(processor, cia,
2086 illegal_instruction_program_interrupt);
2090 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2092 0.36,6.RS,11.RA,16.D:D:::Store Word
2093 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2094 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2095 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2096 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2103 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
2105 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
2106 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2107 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2108 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2109 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2116 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2118 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
2119 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2120 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2121 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2122 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2125 program_interrupt(processor, cia,
2126 illegal_instruction_program_interrupt);
2130 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2132 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
2133 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2134 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2135 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2136 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2139 program_interrupt(processor, cia,
2140 illegal_instruction_program_interrupt);
2144 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2146 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2149 # if (RA_is_0) b = 0;
2151 # EA = b + EXTS(DS_0b00);
2152 # STORE(EA, 8, *rS);
2153 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2156 # if (RA_is_0) b = 0;
2159 # STORE(EA, 8, *rS);
2160 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2163 # program_interrupt(processor, cia
2164 # illegal_instruction_program_interrupt);
2165 # EA = *rA + EXTS(DS_0b00);
2166 # STORE(EA, 8, *rS);
2168 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2171 # program_interrupt(processor, cia
2172 # illegal_instruction_program_interrupt);
2174 # STORE(EA, 8, *rS);
2179 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2182 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2183 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2184 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2185 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2186 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2192 *rT = SWAP_2(MEM(unsigned, EA, 2));
2193 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2195 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2196 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2197 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2198 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2199 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2205 *rT = SWAP_4(MEM(unsigned, EA, 4));
2206 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2208 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2209 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2210 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2211 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2212 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2218 STORE(EA, 2, SWAP_2(*rS));
2219 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2221 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2222 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2223 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2224 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2225 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2231 STORE(EA, 4, SWAP_4(*rS));
2232 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2236 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2239 0.46,6.RT,11.RA,16.D:D:::Load Multiple Word
2248 program_interrupt(processor, cia,
2249 illegal_instruction_program_interrupt);
2250 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT || (EA % 4 != 0))
2251 alignment_interrupt(processor, cia, EA);
2253 GPR(r) = MEM(unsigned, EA, 4);
2258 0.47,6.RS,11.RA,16.D:D:::Store Multiple Word
2265 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT
2267 alignment_interrupt(processor, cia, EA);
2270 STORE(EA, 4, GPR(r));
2277 # I.3.3.6 Fixed-Point Move Assist Instructions
2280 0.31,6.RT,11.RA,16.NB,21.597,31./:X:::Load String Word Immediate
2286 if (RA_is_0) EA = 0;
2288 if (NB == 0) n = 32;
2294 ? (RA >= RT || RA < (RT + nr) % 32)
2295 : (RA >= RT && RA < RT + nr))
2296 program_interrupt(processor, cia,
2297 illegal_instruction_program_interrupt);
2298 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2299 alignment_interrupt(processor, cia, EA);
2305 GPR(r) |= INSERTED(MEM(unsigned, EA, 1), i, i+7);
2306 if (i == 64) i = 32;
2311 0.31,6.RT,11.RA,16.RB,21.533,31./:X:::Load String Word Indexed
2321 n = EXTRACTED32(XER, 25, 31);
2325 if (((RT + nr >= 32)
2326 ? ((RA >= RT || RA < (RT + nr) % 32)
2327 || (RB >= RT || RB < (RT + nr) % 32))
2328 : ((RA >= RT && RA < RT + nr)
2329 || (RB >= RT && RB < RT + nr)))
2330 || (RT == RA || RT == RB))
2331 program_interrupt(processor, cia,
2332 illegal_instruction_program_interrupt);
2333 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2334 alignment_interrupt(processor, cia, EA);
2340 GPR(r) |= INSERTED(MEM(unsigned, EA, 1), i, i+7);
2342 if (i == 64) i = 32;
2347 0.31,6.RS,11.RA,16.NB,21.725,31./:X:::Store String Word Immedate
2352 if (RA_is_0) EA = 0;
2354 if (NB == 0) n = 32;
2358 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2359 alignment_interrupt(processor, cia, EA);
2361 if (i == 32) r = (r + 1) % 32;
2362 STORE(EA, 1, EXTRACTED(GPR(r), i, i+7));
2364 if (i == 64) i = 32;
2369 0.31,6.RS,11.RA,16.RB,21.661,31./:X:::Store String Word Indexed
2378 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2379 alignment_interrupt(processor, cia, EA);
2380 n = EXTRACTED32(XER, 25, 31);
2384 if (i == 32) r = (r + 1) % 32;
2385 STORE(EA, 1, EXTRACTED(GPR(r), i, i+7));
2387 if (i == 64) i = 32;
2394 # I.3.3.7 Storage Synchronization Instructions
2396 # HACK: Rather than monitor addresses looking for a reason
2397 # to cancel a reservation. This code instead keeps
2398 # a copy of the data read from memory. Before performing
2399 # a store, the memory area is checked to see if it has
2401 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2402 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2403 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2404 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2405 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2412 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2413 RESERVE_DATA = MEM(unsigned, EA, 4);
2415 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2417 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2424 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2425 RESERVE_DATA = MEM(unsigned, EA, 8);
2427 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2429 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2430 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2431 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2432 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2433 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2440 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2441 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2443 CR_SET_XER_SO(0, cr_i_zero);
2446 /* ment to randomly to store, we never do! */
2447 CR_SET_XER_SO(0, 0);
2452 CR_SET_XER_SO(0, 0);
2454 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2456 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2463 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2464 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2466 CR_SET_XER_SO(0, cr_i_zero);
2469 /* ment to randomly to store, we never do */
2470 CR_SET_XER_SO(0, 0);
2475 CR_SET_XER_SO(0, 0);
2477 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2479 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2480 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2481 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2482 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2483 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2488 # I.3.3.9 Fixed-Point Arithmetic Instructions
2491 0.14,6.RT,11.RA,16.SI:D:::Add Immediate
2492 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2493 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2494 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2495 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2496 if (RA_is_0) *rT = EXTS(SI);
2497 else *rT = *rA + EXTS(SI);
2498 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2499 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2501 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2502 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2503 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2504 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2505 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2506 if (RA_is_0) *rT = EXTS(SI) << 16;
2507 else *rT = *rA + (EXTS(SI) << 16);
2508 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2509 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2511 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2512 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2513 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2514 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2515 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2518 ALU_END(*rT, 0/*CA*/, OE, Rc);
2519 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2521 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2522 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2523 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2524 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2525 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2530 ALU_END(*rT, 0/*CA*/, OE, Rc);
2531 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2533 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2534 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2535 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2536 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2537 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2540 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2541 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2543 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2544 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2545 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2546 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2547 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2550 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2551 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
2553 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2554 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2555 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2556 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2557 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2562 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2563 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2565 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2566 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2567 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2568 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2569 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2572 ALU_END(*rT, 1/*CA*/, OE, Rc);
2573 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2575 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
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 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2585 ALU_END(*rT, 1/*CA*/, OE, Rc);
2586 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2588 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2589 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2590 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2591 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2592 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2596 ALU_END(*rT, 1/*CA*/, OE, Rc);
2597 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2599 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2600 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2601 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2602 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2603 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2608 ALU_END(*rT, 1/*CA*/, OE, Rc);
2609 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2611 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2612 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2613 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2614 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2615 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2619 ALU_END(*rT, 1/*CA*/, OE, Rc);
2620 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2622 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2623 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2624 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2625 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2626 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2631 ALU_END(*rT, 1/*CA*/, OE, Rc);
2632 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2634 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2635 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2636 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2637 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2638 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2641 ALU_END(*rT, 1/*CA*/, OE, Rc);
2642 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2644 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2645 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2646 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2647 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2648 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2652 ALU_END(*rT, 1/*CA*/, OE, Rc);
2653 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2655 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2656 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2657 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2658 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2659 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2663 ALU_END(*rT,0/*CA*/,OE,Rc);
2664 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2666 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2667 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2668 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2669 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2670 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2671 signed_word prod = *rA * EXTS(SI);
2673 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2675 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2677 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2678 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2679 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2680 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2681 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2682 signed64 a = (signed32)(*rA);
2683 signed64 b = (signed32)(*rB);
2684 signed64 prod = a * b;
2685 signed_word t = prod;
2687 if (t != prod && OE)
2688 XER |= (xer_overflow | xer_summary_overflow);
2689 CR0_COMPARE(t, 0, Rc);
2690 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2692 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2694 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2695 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2696 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2697 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2698 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2699 signed64 a = (signed32)(*rA);
2700 signed64 b = (signed32)(*rB);
2701 signed64 prod = a * b;
2702 signed_word t = EXTRACTED64(prod, 0, 31);
2704 CR0_COMPARE(t, 0, Rc);
2705 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2707 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2709 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::mulhwu:Multiply High Word Unsigned
2710 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2711 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2712 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2713 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2714 unsigned64 a = (unsigned32)(*rA);
2715 unsigned64 b = (unsigned32)(*rB);
2716 unsigned64 prod = a * b;
2717 signed_word t = EXTRACTED64(prod, 0, 31);
2719 CR0_COMPARE(t, 0, Rc);
2720 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2722 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2724 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2725 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2726 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2727 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2728 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2729 signed64 dividend = (signed32)(*rA);
2730 signed64 divisor = (signed32)(*rB);
2731 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2732 || (dividend == 0x80000000 && divisor == -1)) {
2734 XER |= (xer_overflow | xer_summary_overflow);
2735 CR0_COMPARE(0, 0, Rc);
2738 signed64 quotent = dividend / divisor;
2740 CR0_COMPARE((signed_word)quotent, 0, Rc);
2742 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2744 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2746 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2747 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2748 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2749 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2750 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2751 unsigned64 dividend = (unsigned32)(*rA);
2752 unsigned64 divisor = (unsigned32)(*rB);
2755 XER |= (xer_overflow | xer_summary_overflow);
2756 CR0_COMPARE(0, 0, Rc);
2759 unsigned64 quotent = dividend / divisor;
2761 CR0_COMPARE((signed_word)quotent, 0, Rc);
2763 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2767 # I.3.3.10 Fixed-Point Compare Instructions
2770 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2771 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2772 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2773 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2774 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2775 if (!is_64bit_mode && L)
2776 program_interrupt(processor, cia,
2777 illegal_instruction_program_interrupt);
2780 signed_word b = EXTS(SI);
2785 CR_COMPARE(BF, a, b);
2787 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2789 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2790 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2791 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2792 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2793 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2794 if (!is_64bit_mode && L)
2795 program_interrupt(processor, cia,
2796 illegal_instruction_program_interrupt);
2808 CR_COMPARE(BF, a, b);
2810 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2812 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2813 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2814 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2815 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2816 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2817 if (!is_64bit_mode && L)
2818 program_interrupt(processor, cia,
2819 illegal_instruction_program_interrupt);
2822 unsigned_word b = UI;
2824 a = MASKED(*rA, 32, 63);
2827 CR_COMPARE(BF, a, b);
2829 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2831 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2832 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2833 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2834 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2835 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2836 if (!is_64bit_mode && L)
2837 program_interrupt(processor, cia,
2838 illegal_instruction_program_interrupt);
2843 a = MASKED(*rA, 32, 63);
2844 b = MASKED(*rB, 32, 63);
2850 CR_COMPARE(BF, a, b);
2852 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2856 # I.3.3.11 Fixed-Point Trap Instructions
2859 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2861 program_interrupt(processor, cia,
2862 illegal_instruction_program_interrupt);
2864 signed_word a = *rA;
2865 signed_word b = EXTS(SI);
2866 if ((a < b && TO{0})
2868 || (a == b && TO{2})
2869 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2870 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2872 program_interrupt(processor, cia,
2873 trap_program_interrupt);
2876 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2877 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2878 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2879 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2880 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2881 signed_word a = EXTENDED(*rA);
2882 signed_word b = EXTS(SI);
2883 if ((a < b && TO{0})
2885 || (a == b && TO{2})
2886 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2887 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2889 program_interrupt(processor, cia,
2890 trap_program_interrupt);
2892 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2894 program_interrupt(processor, cia,
2895 illegal_instruction_program_interrupt);
2897 signed_word a = *rA;
2898 signed_word b = *rB;
2899 if ((a < b && TO{0})
2901 || (a == b && TO{2})
2902 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2903 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2905 program_interrupt(processor, cia,
2906 trap_program_interrupt);
2909 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2910 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2911 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2912 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2913 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2914 signed_word a = EXTENDED(*rA);
2915 signed_word b = EXTENDED(*rB);
2916 if (TO == 12 && rA == rB) {
2917 ITRACE(trace_breakpoint, ("breakpoint\n"));
2918 cpu_halt(processor, cia, was_trap, 0);
2920 else if ((a < b && TO{0})
2922 || (a == b && TO{2})
2923 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2924 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2926 program_interrupt(processor, cia,
2927 trap_program_interrupt);
2930 # I.3.3.12 Fixed-Point Logical Instructions
2933 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
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
2939 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2940 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2941 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2943 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2944 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2945 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2946 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2947 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2948 *rA = *rS & (UI << 16);
2949 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2950 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2951 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2953 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2954 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2955 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2956 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2957 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2959 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2960 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2962 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
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 | (UI << 16);
2968 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2969 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2971 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2972 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2973 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2974 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2975 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2977 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2978 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2980 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2981 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2982 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2983 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2984 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2985 *rA = *rS ^ (UI << 16);
2986 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2987 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2989 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
2990 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2991 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2992 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2993 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2995 CR0_COMPARE(*rA, 0, Rc);
2996 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2997 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2999 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
3000 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3001 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3002 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3003 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3005 CR0_COMPARE(*rA, 0, Rc);
3006 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3007 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3009 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
3010 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3011 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3012 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3013 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3015 CR0_COMPARE(*rA, 0, Rc);
3016 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3017 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3019 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
3020 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3021 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3022 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3023 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3025 CR0_COMPARE(*rA, 0, Rc);
3026 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3027 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3029 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
3030 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3031 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3032 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3033 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3035 CR0_COMPARE(*rA, 0, Rc);
3036 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3037 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3039 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
3040 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3041 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3042 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3043 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3044 *rA = ~(*rS ^ *rB); /* A === B */
3045 CR0_COMPARE(*rA, 0, Rc);
3046 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3047 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3049 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
3050 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3051 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3052 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3053 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3055 CR0_COMPARE(*rA, 0, Rc);
3056 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3057 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3059 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
3060 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3061 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3062 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3063 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3065 CR0_COMPARE(*rA, 0, Rc);
3066 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3067 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3069 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
3070 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3071 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3072 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3073 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3074 *rA = (signed_word)(signed8)*rS;
3075 CR0_COMPARE(*rA, 0, Rc);
3076 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3077 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3079 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
3080 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3081 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3082 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3083 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3084 *rA = (signed_word)(signed16)*rS;
3085 CR0_COMPARE(*rA, 0, Rc);
3086 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3087 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3089 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
3090 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3091 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3092 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3093 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3094 # *rA = (signed_word)(signed32)*rS;
3095 # CR0_COMPARE(*rA, 0, Rc);
3097 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
3099 # unsigned64 mask = BIT64(0);
3100 # unsigned64 source = *rS;
3101 # while (!(source & mask) && mask != 0) {
3106 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3108 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
3109 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3110 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3111 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3112 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3114 unsigned32 mask = BIT32(0);
3115 unsigned32 source = *rS;
3116 while (!(source & mask) && mask != 0) {
3121 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3122 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3126 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
3129 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
3130 # long n = (sh_5 << 4) | sh_0_4;
3131 # unsigned_word r = ROTL64(*rS, n);
3132 # long b = (mb_5 << 4) | mb_0_4;
3133 # unsigned_word m = MASK(b, 63);
3134 # signed_word result = r & m;
3136 # ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3137 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3139 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
3140 # long n = (sh_5 << 4) | sh_0_4;
3141 # unsigned_word r = ROTL64(*rS, n);
3142 # long e = (me_5 << 4) | me_0_4;
3143 # unsigned_word m = MASK(0, e);
3144 # signed_word result = r & m;
3146 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3148 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
3149 # long n = (sh_5 << 4) | sh_0_4;
3150 # unsigned_word r = ROTL64(*rS, n);
3151 # long b = (mb_5 << 4) | mb_0_4;
3152 # unsigned_word m = MASK(0, (64-n));
3153 # signed_word result = r & m;
3155 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3157 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
3158 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3159 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3160 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3161 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3164 unsigned32 r = ROTL32(s, n);
3165 unsigned32 m = MASK(MB+32, ME+32);
3166 signed_word result = r & m;
3168 CR0_COMPARE(result, 0, Rc);
3170 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
3171 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
3172 (unsigned long)result, (unsigned long)CR));
3173 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3175 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
3176 # long n = MASKED(*rB, 58, 63);
3177 # unsigned_word r = ROTL64(*rS, n);
3178 # long b = (mb_5 << 4) | mb_0_4;
3179 # unsigned_word m = MASK(b, 63);
3180 # signed_word result = r & m;
3182 # CR0_COMPARE(result, 0, Rc);
3184 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
3185 # long n = MASKED(*rB, 58, 63);
3186 # unsigned_word r = ROTL64(*rS, n);
3187 # long e = (me_5 << 4) | me_0_4;
3188 # unsigned_word m = MASK(0, e);
3189 # signed_word result = r & m;
3191 # CR0_COMPARE(result, 0, Rc);
3193 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
3194 long n = MASKED(*rB, 59, 63);
3195 unsigned32 r = ROTL32(*rS, n);
3196 unsigned32 m = MASK(MB+32, ME+32);
3197 signed_word result = r & m;
3199 CR0_COMPARE(result, 0, Rc);
3201 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
3202 # long n = (sh_5 << 4) | sh_0_4;
3203 # unsigned_word r = ROTL64(*rS, n);
3204 # long b = (mb_5 << 4) | mb_0_4;
3205 # unsigned_word m = MASK(b, (64-n));
3206 # signed_word result = (r & m) | (*rA & ~m)
3208 # CR0_COMPARE(result, 0, Rc);
3210 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
3211 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3212 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3213 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3214 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3216 unsigned32 r = ROTL32(*rS, n);
3217 unsigned32 m = MASK(MB+32, ME+32);
3218 signed_word result = (r & m) | (*rA & ~m);
3220 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
3221 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
3222 (unsigned long)result));
3223 CR0_COMPARE(result, 0, Rc);
3224 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3227 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
3229 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
3230 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3231 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3232 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3233 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3234 int n = MASKED(*rB, 58, 63);
3235 unsigned32 source = *rS;
3236 signed_word shifted;
3238 shifted = (source << n);
3242 CR0_COMPARE(shifted, 0, Rc);
3244 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3245 n, (unsigned long)source, (unsigned long)shifted));
3246 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3248 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3250 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
3251 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3252 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3253 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3254 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3255 int n = MASKED(*rB, 58, 63);
3256 unsigned32 source = *rS;
3257 signed_word shifted;
3259 shifted = (source >> n);
3263 CR0_COMPARE(shifted, 0, Rc);
3265 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3266 n, (unsigned long)source, (unsigned long)shifted));
3267 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3269 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3271 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3272 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3273 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3274 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3275 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3277 signed_word r = ROTL32(*rS, /*64*/32-n);
3278 signed_word m = MASK(n+32, 63);
3279 int S = MASKED(*rS, 32, 32);
3280 signed_word shifted = (r & m) | (S ? ~m : 0);
3282 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3286 CR0_COMPARE(shifted, 0, Rc);
3287 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3288 (long)*rA, (long)*rA, (long)XER));
3289 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3291 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3293 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3294 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3295 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3296 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3297 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3299 int n = MASKED(*rB, 59, 63);
3300 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3301 signed32 shifted = source >> n;
3302 int S = (MASKED(*rS,32,32) != 0);
3303 signed64 r = ((unsigned64) source);
3304 r = ((unsigned64) source) << 32 | (unsigned32) source;
3306 if (MASKED(*rB,58,58) == 0)
3307 mask = (unsigned64) MASK64(n+32,63);
3309 mask = (unsigned64) 0;
3310 *rA = (signed_word) (r & mask | ((signed64) -1*S) & ~mask); /* if 64bit will sign extend */
3311 if (S && (MASKED(r & ~mask,32,63)!=0))
3315 CR0_COMPARE(*rA, 0, Rc);
3316 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3317 (long)*rA, (long)*rA, (long)XER));
3318 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3321 # I.3.3.14 Move to/from System Register Instructions
3324 0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3325 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3326 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3327 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3328 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3329 int n = (SPR{5:9} << 5) | SPR{0:4};
3330 if (SPR{0} && IS_PROBLEM_STATE(processor))
3331 program_interrupt(processor, cia,
3332 privileged_instruction_program_interrupt);
3333 else if (!spr_is_valid(n)
3334 || spr_is_readonly(n))
3335 program_interrupt(processor, cia,
3336 illegal_instruction_program_interrupt);
3338 spreg new_val = (spr_length(n) == 64
3340 : MASKED(*rS, 32, 63));
3341 /* HACK - time base registers need to be updated immediatly */
3342 if (WITH_TIME_BASE) {
3345 cpu_set_time_base(processor,
3346 (MASKED64(cpu_get_time_base(processor), 32, 63)
3347 | INSERTED64(new_val, 0, 31)));
3350 cpu_set_time_base(processor,
3351 (MASKED64(cpu_get_time_base(processor), 0, 31)
3352 | INSERTED64(new_val, 32, 63)));
3355 cpu_set_decrementer(processor, new_val);
3366 PPC_INSN_TO_SPR(RS_BITMASK, n);
3368 0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3369 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3370 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3371 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3372 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3373 int n = (SPR{5:9} << 5) | SPR{0:4};
3374 if (SPR{0} && IS_PROBLEM_STATE(processor))
3375 program_interrupt(processor, cia,
3376 privileged_instruction_program_interrupt);
3377 else if (!spr_is_valid(n))
3378 program_interrupt(processor, cia,
3379 illegal_instruction_program_interrupt);
3381 /* HACK - time base registers need to be calculated */
3382 if (WITH_TIME_BASE) {
3385 *rT = cpu_get_decrementer(processor);
3389 /* NOTE - these SPR's are not readable. Use mftb[ul] */
3399 PPC_INSN_FROM_SPR(RT_BITMASK, n);
3401 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3402 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3403 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3404 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3405 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3410 unsigned_word mask = 0;
3412 for (f = 0; f < 8; f++) {
3413 if (FXM & (0x80 >> f))
3414 mask |= (0xf << 4*(7-f));
3416 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3418 PPC_INSN_MTCR(RS_BITMASK, FXM);
3420 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3421 # CR_SET(BF, EXTRACTED32(XER, 0, 3));
3422 # MBLIT32(XER, 0, 3, 0);
3424 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3425 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3426 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3427 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3428 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3429 *rT = (unsigned32)CR;
3430 PPC_INSN_MFCR(RT_BITMASK);
3433 # I.4.6.2 Floating-Point Load Instructions
3436 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3437 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3438 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3439 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3440 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3446 *frT = DOUBLE(MEM(unsigned, EA, 4));
3447 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3449 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3450 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3451 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3452 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3453 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3459 *frT = DOUBLE(MEM(unsigned, EA, 4));
3460 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3462 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3463 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3464 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3465 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3466 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3469 program_interrupt(processor, cia,
3470 illegal_instruction_program_interrupt);
3472 *frT = DOUBLE(MEM(unsigned, EA, 4));
3474 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3476 0.31,6.FRT,11.RA,16.RB,21.567,31./:X:f::Load Floating-Point Single with Update Indexed
3477 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3478 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3479 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3480 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3483 program_interrupt(processor, cia,
3484 illegal_instruction_program_interrupt);
3486 *frT = DOUBLE(MEM(unsigned, EA, 4));
3488 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3490 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3491 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3492 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3493 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3494 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3500 *frT = MEM(unsigned, EA, 8);
3501 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3503 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3504 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3505 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3506 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3507 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3513 *frT = MEM(unsigned, EA, 8);
3514 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3516 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3517 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3518 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3519 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3520 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3523 program_interrupt(processor, cia,
3524 illegal_instruction_program_interrupt);
3526 *frT = MEM(unsigned, EA, 8);
3528 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3530 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3531 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3532 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3533 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3534 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3537 program_interrupt(processor, cia,
3538 illegal_instruction_program_interrupt);
3540 *frT = MEM(unsigned, EA, 8);
3542 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3546 # I.4.6.3 Floating-Point Store Instructions
3549 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3550 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3551 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3552 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3553 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3559 STORE(EA, 4, SINGLE(*frS));
3560 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3562 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3563 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3564 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3565 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3566 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3572 STORE(EA, 4, SINGLE(*frS));
3573 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3575 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3576 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3577 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3578 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3579 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3582 program_interrupt(processor, cia,
3583 illegal_instruction_program_interrupt);
3585 STORE(EA, 4, SINGLE(*frS));
3587 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3589 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3590 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3591 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3592 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3593 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3596 program_interrupt(processor, cia,
3597 illegal_instruction_program_interrupt);
3599 STORE(EA, 4, SINGLE(*frS));
3601 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3603 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3604 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3605 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3606 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3607 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3614 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3616 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3617 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3618 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3619 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3620 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3627 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3629 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3630 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3631 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3632 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3633 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3636 program_interrupt(processor, cia,
3637 illegal_instruction_program_interrupt);
3641 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3643 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3644 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3645 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3646 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3647 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3650 program_interrupt(processor, cia,
3651 illegal_instruction_program_interrupt);
3655 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3659 # I.4.6.4 Floating-Point Move Instructions
3662 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3663 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3664 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3665 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3666 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3669 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3671 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3672 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3673 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3674 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3675 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3676 *frT = *frB ^ BIT64(0);
3678 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3680 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3681 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3682 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3683 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3684 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3685 *frT = *frB & ~BIT64(0);
3687 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3689 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3690 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3691 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3692 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3693 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3694 *frT = *frB | BIT64(0);
3696 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3700 # I.4.6.5 Floating-Point Arithmetic Instructions
3703 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3704 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3705 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3706 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3707 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3709 if (is_invalid_operation(processor, cia,
3711 fpscr_vxsnan | fpscr_vxisi,
3714 invalid_arithemetic_operation(processor, cia,
3716 0, /*instruction_is_frsp*/
3717 0, /*instruction_is_convert_to_64bit*/
3718 0, /*instruction_is_convert_to_32bit*/
3719 0); /*single-precision*/
3723 double s = *(double*)frA + *(double*)frB;
3727 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3729 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3730 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3731 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3732 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3733 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3735 if (is_invalid_operation(processor, cia,
3737 fpscr_vxsnan | fpscr_vxisi,
3740 invalid_arithemetic_operation(processor, cia,
3742 0, /*instruction_is_frsp*/
3743 0, /*instruction_is_convert_to_64bit*/
3744 0, /*instruction_is_convert_to_32bit*/
3745 1); /*single-precision*/
3749 float s = *(double*)frA + *(double*)frB;
3753 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3755 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3756 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3757 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3758 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3759 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3761 if (is_invalid_operation(processor, cia,
3763 fpscr_vxsnan | fpscr_vxisi,
3766 invalid_arithemetic_operation(processor, cia,
3768 0, /*instruction_is_frsp*/
3769 0, /*instruction_is_convert_to_64bit*/
3770 0, /*instruction_is_convert_to_32bit*/
3771 0); /*single-precision*/
3775 double s = *(double*)frA - *(double*)frB;
3779 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3781 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3782 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3783 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3784 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3785 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3787 if (is_invalid_operation(processor, cia,
3789 fpscr_vxsnan | fpscr_vxisi,
3792 invalid_arithemetic_operation(processor, cia,
3794 0, /*instruction_is_frsp*/
3795 0, /*instruction_is_convert_to_64bit*/
3796 0, /*instruction_is_convert_to_32bit*/
3797 1); /*single-precision*/
3801 float s = *(double*)frA - *(double*)frB;
3805 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3807 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3808 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3809 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3810 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3811 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3813 if (is_invalid_operation(processor, cia,
3815 fpscr_vxsnan | fpscr_vximz,
3818 invalid_arithemetic_operation(processor, cia,
3820 0, /*instruction_is_frsp*/
3821 0, /*instruction_is_convert_to_64bit*/
3822 0, /*instruction_is_convert_to_32bit*/
3823 0); /*single-precision*/
3827 double s = *(double*)frA * *(double*)frC;
3831 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3833 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3834 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3835 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3836 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3837 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3839 if (is_invalid_operation(processor, cia,
3841 fpscr_vxsnan | fpscr_vximz,
3844 invalid_arithemetic_operation(processor, cia,
3846 0, /*instruction_is_frsp*/
3847 0, /*instruction_is_convert_to_64bit*/
3848 0, /*instruction_is_convert_to_32bit*/
3849 1); /*single-precision*/
3853 float s = *(double*)frA * *(double*)frC;
3857 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3859 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3860 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3861 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3862 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3863 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3865 if (is_invalid_operation(processor, cia,
3867 fpscr_vxsnan | fpscr_vxzdz,
3870 invalid_arithemetic_operation(processor, cia,
3872 0, /*instruction_is_frsp*/
3873 0, /*instruction_is_convert_to_64bit*/
3874 0, /*instruction_is_convert_to_32bit*/
3875 0); /*single-precision*/
3877 else if (is_invalid_zero_divide (processor, cia,
3880 invalid_zero_divide_operation (processor, cia,
3886 double s = *(double*)frA / *(double*)frB;
3890 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3892 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3893 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3894 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3895 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3896 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3898 if (is_invalid_operation(processor, cia,
3900 fpscr_vxsnan | fpscr_vxzdz,
3903 invalid_arithemetic_operation(processor, cia,
3905 0, /*instruction_is_frsp*/
3906 0, /*instruction_is_convert_to_64bit*/
3907 0, /*instruction_is_convert_to_32bit*/
3908 1); /*single-precision*/
3910 else if (is_invalid_zero_divide (processor, cia,
3913 invalid_zero_divide_operation (processor, cia,
3919 float s = *(double*)frA / *(double*)frB;
3923 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3925 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3926 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3927 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3928 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3929 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3931 double product; /*HACK! - incorrectly loosing precision ... */
3932 /* compute the multiply */
3933 if (is_invalid_operation(processor, cia,
3935 fpscr_vxsnan | fpscr_vximz,
3938 invalid_arithemetic_operation(processor, cia,
3939 (unsigned64*)&product, *frA, 0, *frC,
3940 0, /*instruction_is_frsp*/
3941 0, /*instruction_is_convert_to_64bit*/
3942 0, /*instruction_is_convert_to_32bit*/
3943 0); /*single-precision*/
3947 product = *(double*)frA * *(double*)frC;
3949 /* compute the add */
3950 if (is_invalid_operation(processor, cia,
3952 fpscr_vxsnan | fpscr_vxisi,
3955 invalid_arithemetic_operation(processor, cia,
3956 frT, product, *frB, 0,
3957 0, /*instruction_is_frsp*/
3958 0, /*instruction_is_convert_to_64bit*/
3959 0, /*instruction_is_convert_to_32bit*/
3960 0); /*single-precision*/
3964 double s = product + *(double*)frB;
3968 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3970 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3971 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3972 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3973 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3974 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3976 float product; /*HACK! - incorrectly loosing precision ... */
3977 /* compute the multiply */
3978 if (is_invalid_operation(processor, cia,
3980 fpscr_vxsnan | fpscr_vximz,
3983 invalid_arithemetic_operation(processor, cia,
3984 (unsigned64*)&product, *frA, 0, *frC,
3985 0, /*instruction_is_frsp*/
3986 0, /*instruction_is_convert_to_64bit*/
3987 0, /*instruction_is_convert_to_32bit*/
3988 0); /*single-precision*/
3992 product = *(double*)frA * *(double*)frC;
3994 /* compute the add */
3995 if (is_invalid_operation(processor, cia,
3997 fpscr_vxsnan | fpscr_vxisi,
4000 invalid_arithemetic_operation(processor, cia,
4001 frT, product, *frB, 0,
4002 0, /*instruction_is_frsp*/
4003 0, /*instruction_is_convert_to_64bit*/
4004 0, /*instruction_is_convert_to_32bit*/
4005 0); /*single-precision*/
4009 float s = product + *(double*)frB;
4010 *(double*)frT = (double)s;
4013 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4015 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
4016 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4017 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4018 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4019 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4021 double product; /*HACK! - incorrectly loosing precision ... */
4022 /* compute the multiply */
4023 if (is_invalid_operation(processor, cia,
4025 fpscr_vxsnan | fpscr_vximz,
4028 invalid_arithemetic_operation(processor, cia,
4029 (unsigned64*)&product, *frA, 0, *frC,
4030 0, /*instruction_is_frsp*/
4031 0, /*instruction_is_convert_to_64bit*/
4032 0, /*instruction_is_convert_to_32bit*/
4033 0); /*single-precision*/
4037 product = *(double*)frA * *(double*)frC;
4039 /* compute the subtract */
4040 if (is_invalid_operation(processor, cia,
4042 fpscr_vxsnan | fpscr_vxisi,
4045 invalid_arithemetic_operation(processor, cia,
4046 frT, product, *frB, 0,
4047 0, /*instruction_is_frsp*/
4048 0, /*instruction_is_convert_to_64bit*/
4049 0, /*instruction_is_convert_to_32bit*/
4050 0); /*single-precision*/
4054 double s = product - *(double*)frB;
4058 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4060 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
4061 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4062 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4063 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4064 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4066 float product; /*HACK! - incorrectly loosing precision ... */
4067 /* compute the multiply */
4068 if (is_invalid_operation(processor, cia,
4070 fpscr_vxsnan | fpscr_vximz,
4073 invalid_arithemetic_operation(processor, cia,
4074 (unsigned64*)&product, *frA, 0, *frC,
4075 0, /*instruction_is_frsp*/
4076 0, /*instruction_is_convert_to_64bit*/
4077 0, /*instruction_is_convert_to_32bit*/
4078 0); /*single-precision*/
4082 product = *(double*)frA * *(double*)frC;
4084 /* compute the subtract */
4085 if (is_invalid_operation(processor, cia,
4087 fpscr_vxsnan | fpscr_vxisi,
4090 invalid_arithemetic_operation(processor, cia,
4091 frT, product, *frB, 0,
4092 0, /*instruction_is_frsp*/
4093 0, /*instruction_is_convert_to_64bit*/
4094 0, /*instruction_is_convert_to_32bit*/
4095 0); /*single-precision*/
4099 float s = product - *(double*)frB;
4100 *(double*)frT = (double)s;
4103 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4105 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
4106 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4107 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4108 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4109 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4111 double product; /*HACK! - incorrectly loosing precision ... */
4112 /* compute the multiply */
4113 if (is_invalid_operation(processor, cia,
4115 fpscr_vxsnan | fpscr_vximz,
4118 invalid_arithemetic_operation(processor, cia,
4119 (unsigned64*)&product, *frA, 0, *frC,
4120 0, /*instruction_is_frsp*/
4121 0, /*instruction_is_convert_to_64bit*/
4122 0, /*instruction_is_convert_to_32bit*/
4123 0); /*single-precision*/
4127 product = *(double*)frA * *(double*)frC;
4129 /* compute the add */
4130 if (is_invalid_operation(processor, cia,
4132 fpscr_vxsnan | fpscr_vxisi,
4135 invalid_arithemetic_operation(processor, cia,
4136 frT, product, *frB, 0,
4137 0, /*instruction_is_frsp*/
4138 0, /*instruction_is_convert_to_64bit*/
4139 0, /*instruction_is_convert_to_32bit*/
4140 0); /*single-precision*/
4144 double s = -(product + *(double*)frB);
4148 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4150 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
4151 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4152 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4153 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4154 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4156 float product; /*HACK! - incorrectly loosing precision ... */
4157 /* compute the multiply */
4158 if (is_invalid_operation(processor, cia,
4160 fpscr_vxsnan | fpscr_vximz,
4163 invalid_arithemetic_operation(processor, cia,
4164 (unsigned64*)&product, *frA, 0, *frC,
4165 0, /*instruction_is_frsp*/
4166 0, /*instruction_is_convert_to_64bit*/
4167 0, /*instruction_is_convert_to_32bit*/
4168 0); /*single-precision*/
4172 product = *(double*)frA * *(double*)frC;
4174 /* compute the add */
4175 if (is_invalid_operation(processor, cia,
4177 fpscr_vxsnan | fpscr_vxisi,
4180 invalid_arithemetic_operation(processor, cia,
4181 frT, product, *frB, 0,
4182 0, /*instruction_is_frsp*/
4183 0, /*instruction_is_convert_to_64bit*/
4184 0, /*instruction_is_convert_to_32bit*/
4185 0); /*single-precision*/
4189 float s = -(product + *(double*)frB);
4190 *(double*)frT = (double)s;
4193 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4195 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
4196 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4197 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4198 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4199 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4201 double product; /*HACK! - incorrectly loosing precision ... */
4202 /* compute the multiply */
4203 if (is_invalid_operation(processor, cia,
4205 fpscr_vxsnan | fpscr_vximz,
4208 invalid_arithemetic_operation(processor, cia,
4209 (unsigned64*)&product, *frA, 0, *frC,
4210 0, /*instruction_is_frsp*/
4211 0, /*instruction_is_convert_to_64bit*/
4212 0, /*instruction_is_convert_to_32bit*/
4213 0); /*single-precision*/
4217 product = *(double*)frA * *(double*)frC;
4219 /* compute the subtract */
4220 if (is_invalid_operation(processor, cia,
4222 fpscr_vxsnan | fpscr_vxisi,
4225 invalid_arithemetic_operation(processor, cia,
4226 frT, product, *frB, 0,
4227 0, /*instruction_is_frsp*/
4228 0, /*instruction_is_convert_to_64bit*/
4229 0, /*instruction_is_convert_to_32bit*/
4230 0); /*single-precision*/
4234 double s = -(product - *(double*)frB);
4238 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4240 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
4241 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4242 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4243 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4244 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4246 float product; /*HACK! - incorrectly loosing precision ... */
4247 /* compute the multiply */
4248 if (is_invalid_operation(processor, cia,
4250 fpscr_vxsnan | fpscr_vximz,
4253 invalid_arithemetic_operation(processor, cia,
4254 (unsigned64*)&product, *frA, 0, *frC,
4255 0, /*instruction_is_frsp*/
4256 0, /*instruction_is_convert_to_64bit*/
4257 0, /*instruction_is_convert_to_32bit*/
4258 0); /*single-precision*/
4262 product = *(double*)frA * *(double*)frC;
4264 /* compute the subtract */
4265 if (is_invalid_operation(processor, cia,
4267 fpscr_vxsnan | fpscr_vxisi,
4270 invalid_arithemetic_operation(processor, cia,
4271 frT, product, *frB, 0,
4272 0, /*instruction_is_frsp*/
4273 0, /*instruction_is_convert_to_64bit*/
4274 0, /*instruction_is_convert_to_32bit*/
4275 0); /*single-precision*/
4279 float s = -(product - *(double*)frB);
4280 *(double*)frT = (double)s;
4283 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4287 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4290 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4291 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4292 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4293 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4294 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4297 unsigned64 frac_grx;
4299 /* split off cases for what to do */
4300 if (EXTRACTED64(*frB, 1, 11) < 897
4301 && EXTRACTED64(*frB, 1, 63) > 0) {
4302 if ((FPSCR & fpscr_ue) == 0) GOTO(Disabled_Exponent_Underflow);
4303 if ((FPSCR & fpscr_ue) != 0) GOTO(Enabled_Exponent_Underflow);
4305 if (EXTRACTED64(*frB, 1, 11) > 1150
4306 && EXTRACTED64(*frB, 1, 11) < 2047) {
4307 if ((FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4308 if ((FPSCR & fpscr_oe) != 0) GOTO(Enabled_Exponent_Overflow);
4310 if (EXTRACTED64(*frB, 1, 11) > 896
4311 && EXTRACTED64(*frB, 1, 11) < 1151) GOTO(Normal_Operand);
4312 if (EXTRACTED64(*frB, 1, 63) == 0) GOTO(Zero_Operand);
4313 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4314 if (EXTRACTED64(*frB, 12, 63) == 0) GOTO(Infinity_Operand);
4315 if (EXTRACTED64(*frB, 12, 12) == 1) GOTO(QNaN_Operand);
4316 if (EXTRACTED64(*frB, 12, 12) == 0
4317 && EXTRACTED64(*frB, 13, 63) > 0) GOTO(SNaN_Operand);
4320 LABEL(Disabled_Exponent_Underflow):
4321 sign = EXTRACTED64(*frB, 0, 0);
4322 if (EXTRACTED64(*frB, 1, 11) == 0) {
4324 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4326 if (EXTRACTED64(*frB, 1, 11) > 0) {
4327 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4328 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4330 /* G|R|X == zero from above */
4331 while (exp < -126) {
4333 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4334 | MASKED64(frac_grx, 55, 55));
4336 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4337 Round_Single(processor, sign, &exp, &frac_grx);
4338 FPSCR_SET_XX(FPSCR & fpscr_fi);
4339 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4340 *frT = INSERTED64(sign, 0, 0);
4341 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4342 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4344 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4345 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4346 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4347 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4349 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4350 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4351 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4353 /*Normalize_Operand:*/
4354 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4356 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4358 *frT = (INSERTED64(sign, 0, 0)
4359 | INSERTED64(exp + 1023, 1, 11)
4360 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4364 LABEL(Enabled_Exponent_Underflow):
4366 sign = EXTRACTED64(*frB, 0, 0);
4367 if (EXTRACTED64(*frB, 1, 11) == 0) {
4369 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4371 if (EXTRACTED64(*frB, 1, 11) > 0) {
4372 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4373 frac_grx = (BIT64(0) |
4374 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4376 /*Normalize_Operand:*/
4377 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4379 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4381 Round_Single(processor, sign, &exp, &frac_grx);
4382 FPSCR_SET_XX(FPSCR & fpscr_fi);
4384 *frT = (INSERTED64(sign, 0, 0)
4385 | INSERTED64(exp + 1023, 1, 11)
4386 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4387 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4388 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4391 LABEL(Disabled_Exponent_Overflow):
4393 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4394 if (EXTRACTED64(*frB, 0, 0) == 0) {
4395 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4396 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4398 if (EXTRACTED64(*frB, 0, 0) == 1) {
4399 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4400 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4403 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4404 if (EXTRACTED64(*frB, 0, 0) == 0) {
4405 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4406 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4408 if (EXTRACTED64(*frB, 0, 0) == 1) {
4409 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4410 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4413 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4414 if (EXTRACTED64(*frB, 0, 0) == 0) {
4415 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4416 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4418 if (EXTRACTED64(*frB, 0, 0) == 1) {
4419 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4420 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4423 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4424 if (EXTRACTED64(*frB, 0, 0) == 0) {
4425 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4426 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4428 if (EXTRACTED64(*frB, 0, 0) == 1) {
4429 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4430 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4433 /* FPSCR[FR] <- undefined */
4438 LABEL(Enabled_Exponent_Overflow):
4439 sign = EXTRACTED64(*frB, 0, 0);
4440 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4441 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4442 Round_Single(processor, sign, &exp, &frac_grx);
4443 FPSCR_SET_XX(FPSCR & fpscr_fi);
4445 LABEL(Enabled_Overflow):
4448 *frT = (INSERTED64(sign, 0, 0)
4449 | INSERTED64(exp + 1023, 1, 11)
4450 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4451 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4452 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4455 LABEL(Zero_Operand):
4457 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4458 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4463 LABEL(Infinity_Operand):
4465 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4466 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4471 LABEL(QNaN_Operand):
4472 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4473 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4478 LABEL(SNaN_Operand):
4479 FPSCR_OR_VX(fpscr_vxsnan);
4480 if ((FPSCR & fpscr_ve) == 0) {
4481 *frT = (MASKED64(*frB, 0, 11)
4483 | MASKED64(*frB, 13, 34));
4484 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4490 LABEL(Normal_Operand):
4491 sign = EXTRACTED64(*frB, 0, 0);
4492 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4493 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4494 Round_Single(processor, sign, &exp, &frac_grx);
4495 FPSCR_SET_XX(FPSCR & fpscr_fi);
4496 if (exp > 127 && (FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4497 if (exp > 127 && (FPSCR & fpscr_oe) != 0) GOTO(Enabled_Overflow);
4498 *frT = (INSERTED64(sign, 0, 0)
4499 | INSERTED64(exp + 1023, 1, 11)
4500 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4501 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4502 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4506 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4509 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4510 floating_point_assist_interrupt(processor, cia);
4512 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4513 floating_point_assist_interrupt(processor, cia);
4515 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4516 floating_point_assist_interrupt(processor, cia);
4518 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
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
4524 convert_to_integer(processor, cia,
4526 fpscr_rn_round_towards_zero, 32);
4528 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4530 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4531 int sign = EXTRACTED64(*frB, 0, 0);
4533 unsigned64 frac = *frB;
4535 if (frac == 0) GOTO(Zero_Operand);
4536 if (sign == 1) frac = ~frac + 1;
4537 while (EXTRACTED64(frac, 0, 0) == 0) {
4538 /*??? do the loop 0 times if (FRB) = max negative integer */
4539 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4542 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4543 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4544 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4545 *frT = (INSERTED64(sign, 0, 0)
4546 | INSERTED64(exp + 1023, 1, 11)
4547 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4550 LABEL(Zero_Operand):
4553 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4558 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4562 # I.4.6.7 Floating-Point Compare Instructions
4565 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4566 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4567 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4568 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4569 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4572 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4573 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4574 else if (is_less_than(frA, frB))
4575 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4576 else if (is_greater_than(frA, frB))
4577 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4579 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4581 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4582 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4583 FPSCR_OR_VX(fpscr_vxsnan);
4585 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4587 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4588 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4589 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4590 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4591 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4594 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4595 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4596 else if (is_less_than(frA, frB))
4597 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4598 else if (is_greater_than(frA, frB))
4599 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4601 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4603 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4604 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4605 FPSCR_OR_VX(fpscr_vxsnan);
4606 if ((FPSCR & fpscr_ve) == 0)
4607 FPSCR_OR_VX(fpscr_vxvc);
4609 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4610 FPSCR_OR_VX(fpscr_vxvc);
4613 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4617 # I.4.6.8 Floating-Point Status and Control Register Instructions
4620 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4625 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4627 unsigned field = FPSCR_FIELD(BFA);
4629 FPSCR_SET(BFA, 0); /* FPSCR_END fixes up FEX/VX */
4632 0.63,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4637 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4640 for (i = 0; i < 8; i++) {
4641 if ((FLM & BIT8(i))) {
4642 FPSCR &= ~MASK32(i*4, i*4+3);
4643 FPSCR |= MASKED32(*frB, i*4, i*4+3);
4648 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4650 unsigned32 bit = BIT32(BT);
4654 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4656 unsigned32 bit = BIT32(BT);
4659 if ((bit & fpscr_vx_bits))
4661 /* note - omit vx bit */
4662 if ((bit & (fpscr_ox | fpscr_ux | fpscr_zx | fpscr_xx)))
4669 # I.A.1.1 Floating-Point Store Instruction
4671 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f,o::Store Floating-Point as Integer Word Indexed
4672 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4675 # I.A.1.2 Floating-Point Arithmetic Instructions
4678 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root
4679 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4681 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root Single
4682 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4684 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f,o::Floating Reciprocal Estimate Single
4685 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4687 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f,o::Floating Reciprocal Square Root Estimate
4688 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4691 # I.A.1.3 Floating-Point Select Instruction
4694 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f,o::Floating Select
4695 *601: PPC_UNIT_BAD, PPC_UNIT_BAD, 0, 0, 0
4696 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4697 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4698 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4699 if (CURRENT_MODEL == MODEL_ppc601) {
4700 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4702 unsigned64 zero = 0;
4704 if (is_NaN(*frA, 0) || is_less_than (frA, &zero)) *frT = *frB;
4707 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4711 # II.3.2 Cache Management Instructions
4714 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4715 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4716 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4717 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4718 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4719 /* blindly flush all instruction cache entries */
4720 #if WITH_IDECODE_CACHE_SIZE
4721 cpu_flush_icache(processor);
4723 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4725 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4726 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4727 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4728 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4729 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4730 cpu_synchronize_context(processor, cia);
4731 PPC_INSN_INT(0, 0, 0);
4735 # II.3.2.2 Data Cache Instructions
4738 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4739 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4740 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4741 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4742 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4743 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4744 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4746 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4747 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4748 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4749 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4750 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4751 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4752 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4754 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4755 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4756 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4757 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4758 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4759 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4760 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4762 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4763 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4764 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4765 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4766 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4767 TRACE(trace_tbd,("Data Cache Block Store\n"));
4768 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4770 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4771 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4772 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4773 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4774 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4775 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4776 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4779 # II.3.3 Enforce In-order Execution of I/O Instruction
4782 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4783 /* Since this model has no instruction overlap
4784 this instruction need do nothing */
4787 # II.4.1 Time Base Instructions
4790 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4791 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4792 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4793 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4794 int n = (tbr{5:9} << 5) | tbr{0:4};
4796 if (is_64bit_implementation) *rT = TB;
4797 else *rT = EXTRACTED64(TB, 32, 63);
4799 else if (n == 269) {
4800 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4801 else *rT = EXTRACTED64(TB, 0, 31);
4804 program_interrupt(processor, cia,
4805 illegal_instruction_program_interrupt);
4809 # III.2.3.1 System Linkage Instructions
4812 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4813 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4814 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4815 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4816 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4817 if (IS_PROBLEM_STATE(processor)) {
4818 program_interrupt(processor, cia,
4819 privileged_instruction_program_interrupt);
4822 MSR = (MASKED(SRR1, 0, 32)
4823 | MASKED(SRR1, 37, 41)
4824 | MASKED(SRR1, 48, 63));
4825 NIA = MASKED(SRR0, 0, 61);
4826 cpu_synchronize_context(processor, cia);
4827 check_masked_interrupts(processor);
4831 # III.3.4.1 Move to/from System Register Instructions
4834 #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4835 #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4836 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4837 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4838 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4839 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4840 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4841 if (IS_PROBLEM_STATE(processor))
4842 program_interrupt(processor, cia,
4843 privileged_instruction_program_interrupt);
4846 check_masked_interrupts(processor);
4849 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4850 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4851 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4852 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4853 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4854 if (IS_PROBLEM_STATE(processor))
4855 program_interrupt(processor, cia,
4856 privileged_instruction_program_interrupt);
4859 check_masked_interrupts(processor);
4864 # III.4.11.1 Cache Management Instructions
4867 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4868 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4869 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4870 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4871 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4872 if (IS_PROBLEM_STATE(processor))
4873 program_interrupt(processor, cia,
4874 privileged_instruction_program_interrupt);
4876 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4879 # III.4.11.2 Segment Register Manipulation Instructions
4882 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4883 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4884 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4885 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4886 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4887 if (IS_PROBLEM_STATE(processor))
4888 program_interrupt(processor, cia,
4889 privileged_instruction_program_interrupt);
4893 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4894 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4895 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4896 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4897 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4898 if (IS_PROBLEM_STATE(processor))
4899 program_interrupt(processor, cia,
4900 privileged_instruction_program_interrupt);
4902 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4904 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4905 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4906 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4907 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4908 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4909 if (IS_PROBLEM_STATE(processor))
4910 program_interrupt(processor, cia,
4911 privileged_instruction_program_interrupt);
4915 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4916 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4917 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4918 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4919 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4920 if (IS_PROBLEM_STATE(processor))
4921 program_interrupt(processor, cia,
4922 privileged_instruction_program_interrupt);
4924 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4928 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4931 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4933 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4935 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4936 if (IS_PROBLEM_STATE(processor))
4937 program_interrupt(processor, cia,
4938 privileged_instruction_program_interrupt);
4943 proc = psim_cpu(cpu_system(processor), nr);
4944 if (proc == NULL) break;
4945 cpu_page_tlb_invalidate_entry(proc, *rB);
4950 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4951 if (IS_PROBLEM_STATE(processor))
4952 program_interrupt(processor, cia,
4953 privileged_instruction_program_interrupt);
4958 proc = psim_cpu(cpu_system(processor), nr);
4959 if (proc == NULL) break;
4960 cpu_page_tlb_invalidate_all(proc);
4965 0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
4966 /* nothing happens here - always in sync */
4969 # III.A.1.2 External Access Instructions
4972 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4974 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed