2 # This file is part of the program psim.
4 # Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
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.
41 # 1 Instruction format as a `start-bit,content' pairs.
42 # the content is one of a digit, field name or `/' (aka.0)
46 # 3 Flags: 64 - 64bit only
47 # f - floating point enabled required
54 # For flags marked 'model', the fields are interpreted as follows:
62 # 4 String name for model
64 # 5 Specific CPU model, must be an identifier
66 # 6 Comma separated list of functional units
70 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
71 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
72 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
73 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
77 typedef enum _ppc_function_unit {
78 PPC_UNIT_BAD, /* unknown function unit */
79 PPC_UNIT_IU, /* integer unit (601/603 style) */
80 PPC_UNIT_SRU, /* system register unit (601/603 style) */
81 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
82 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
83 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
84 PPC_UNIT_FPU, /* floating point unit */
85 PPC_UNIT_LSU, /* load/store unit */
86 PPC_UNIT_BPU, /* branch unit */
90 /* Structure to hold timing information on a per instruction basis */
92 ppc_function_unit first_unit; /* first functional unit this insn could use */
93 ppc_function_unit second_unit; /* second functional unit this insn could use */
94 signed16 issue; /* # cycles before function unit can process other insns */
95 signed16 done; /* # cycles before insn is done */
96 unsigned32 flags; /* any flags that are needed */
99 /* Register mappings in status masks */
100 #define PPC_CR_REG 0 /* start of CR0 .. CR7 */
101 #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */
103 #define PPC_NO_SPR (-1) /* flag for no SPR register */
105 /* Structure for each functional unit that is busy */
106 typedef struct _model_busy model_busy;
108 model_busy *next; /* next function unit */
109 ppc_function_unit unit; /* function unit name */
110 unsigned32 int_busy; /* int registers that are busy */
111 unsigned32 fp_busy; /* floating point registers that are busy */
112 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
113 signed16 spr_busy; /* SPR register that is busy or PPC_NO_SPR */
114 signed8 issue; /* # of cycles until unit can accept another insn */
115 signed8 done; /* # of cycles until insn is done */
118 /* Structure to hold the current state information for the simulated CPU model */
120 cpu *processor; /* point back to processor */
121 const char *name; /* model name */
122 const model_time *timing; /* timing information */
123 model_busy *busy_list; /* list of busy function units */
124 model_busy *free_list; /* list of model_busy structs not in use */
125 count_type nr_cycles; /* # cycles */
126 count_type nr_branches; /* # branches */
127 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
128 count_type nr_branch_predict_trues; /* # branches predicted correctly */
129 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
130 count_type nr_stalls_data; /* # of stalls for data */
131 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
132 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
133 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
134 unsigned32 int_busy; /* int registers that are busy */
135 unsigned32 fp_busy; /* floating point registers that are busy */
136 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
137 unsigned8 spr_busy[nr_of_sprs]; /* SPR registers that are busy */
138 unsigned8 busy[nr_ppc_function_units]; /* whether a function is busy or not */
141 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
142 "unknown functional unit instruction",
143 "integer functional unit instruction",
144 "system register functional unit instruction",
145 "1st single cycle integer functional unit instruction",
146 "2nd single cycle integer functional unit instruction",
147 "multiple cycle integer functional unit instruction",
148 "floating point functional unit instruction",
149 "load/store functional unit instruction",
150 "branch functional unit instruction",
154 # Trace releasing resources
155 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
157 TRACE(trace_model,("done, %s\n", ppc_function_unit_name[busy->unit]));
158 if (busy->int_busy) {
159 for(i = 0; i < 32; i++) {
160 if (((1 << i) & busy->int_busy) != 0) {
161 TRACE(trace_model, ("Register r%d is now available.\n", i));
166 for(i = 0; i < 32; i++) {
167 if (((1 << i) & busy->fp_busy) != 0) {
168 TRACE(trace_model, ("Register f%d is now available.\n", i));
172 if (busy->cr_fpscr_busy) {
173 for(i = 0; i < 8; i++) {
174 if (((1 << i) & busy->cr_fpscr_busy) != 0) {
175 TRACE(trace_model, ("Register cr%d is now available.\n", i));
178 if (busy->cr_fpscr_busy & 0x100)
179 TRACE(trace_model, ("Register fpscr is now available.\n"));
181 if (busy->spr_busy != PPC_NO_SPR)
182 TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
184 # Trace waiting for registers to become available
185 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
188 int_busy &= model_ptr->int_busy;
189 for(i = 0; i < 32; i++) {
190 if (((1 << i) & int_busy) != 0) {
191 TRACE(trace_model, ("Waiting for register r%d.\n", i));
196 fp_busy &= model_ptr->fp_busy;
197 for(i = 0; i < 32; i++) {
198 if (((1 << i) & fp_busy) != 0) {
199 TRACE(trace_model, ("Waiting for register f%d.\n", i));
203 if (cr_or_fpscr_busy) {
204 cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
205 for(i = 0; i < 8; i++) {
206 if (((1 << i) & cr_or_fpscr_busy) != 0) {
207 TRACE(trace_model, ("Waiting for register cr%d.\n", i));
210 if (cr_or_fpscr_busy & 0x100)
211 TRACE(trace_model, ("Waiting for register fpscr.\n"));
213 if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
214 TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
216 # Advance state to next cycle, releasing any registers allocated
217 void::model-internal::model_new_cycle:model_data *model_ptr
218 model_busy *cur_busy = model_ptr->busy_list;
219 model_busy *free_list = model_ptr->free_list;
220 model_busy *next_busy = (model_busy *)0;
223 model_ptr->nr_cycles++;
224 for ( ; cur_busy; cur_busy = next) {
225 next = cur_busy->next;
226 if (--cur_busy->done <= 0) { /* function unit done, release registers */
227 model_ptr->int_busy &= ~cur_busy->int_busy;
228 model_ptr->fp_busy &= ~cur_busy->fp_busy;
229 model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
230 if (cur_busy->spr_busy != PPC_NO_SPR)
231 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
233 if (WITH_TRACE && ppc_trace[trace_model])
234 model_trace_release(model_ptr, cur_busy);
236 model_ptr->busy[cur_busy->unit] = 0;
237 cur_busy->next = free_list;
238 free_list = cur_busy;
240 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
241 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
242 model_ptr->busy[cur_busy->unit] = 0;
243 cur_busy->next = next_busy;
244 next_busy = cur_busy;
247 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
248 ppc_function_unit_name[cur_busy->unit],
251 cur_busy->next = next_busy;
252 next_busy = cur_busy;
256 model_ptr->busy_list = next_busy;
257 model_ptr->free_list = free_list;
259 # Mark a function unit as busy, return the busy structure
260 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
263 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
265 if (!model_ptr->free_list) {
266 busy = ZALLOC(model_busy);
269 busy = model_ptr->free_list;
270 model_ptr->free_list = busy->next;
272 busy->next = model_ptr->busy_list;
278 busy->cr_fpscr_busy = 0;
279 busy->spr_busy = PPC_NO_SPR;
280 model_ptr->busy_list = busy;
281 model_ptr->busy[unit] = 1;
282 model_ptr->nr_units[unit]++;
285 # Make a given integer register busy
286 void::model-internal::model_make_int_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
287 TRACE(trace_model,("Marking register r%d as busy\n", regno));
288 busy_ptr->int_busy |= (1 << regno);
289 model_ptr->int_busy |= (1 << regno);
291 # Make a given floating point register busy
292 void::model-internal::model_make_fp_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
293 TRACE(trace_model,("Marking register f%d as busy\n", regno));
294 busy_ptr->fp_busy |= (1 << regno);
295 model_ptr->fp_busy |= (1 << regno);
297 # Make a given CR register busy
298 void::model-internal::model_make_cr_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
299 TRACE(trace_model,("Marking register cr%d as busy\n", regno));
300 busy_ptr->cr_fpscr_busy |= (1 << regno);
301 model_ptr->cr_fpscr_busy |= (1 << regno);
303 # Make a given SPR register busy
304 void::model-internal::model_make_spr_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
305 TRACE(trace_model,("Marking register %s as busy\n", spr_name(regno)));
306 busy_ptr->spr_busy = regno;
307 model_ptr->spr_busy[regno] = 1;
310 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
311 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
312 ppc_function_unit first_unit = time_ptr->first_unit;
313 ppc_function_unit second_unit = time_ptr->second_unit;
314 int stall_increment = 0;
317 if (!model_ptr->busy[first_unit])
318 return model_make_busy(model_ptr, first_unit,
319 model_ptr->timing[index].issue,
320 model_ptr->timing[index].done);
322 if (!model_ptr->busy[second_unit])
323 return model_make_busy(model_ptr, second_unit,
324 model_ptr->timing[index].issue,
325 model_ptr->timing[index].done);
327 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
328 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
330 model_new_cycle(model_ptr);
333 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
334 void::model-function::model_serialize:itable_index index, model_data *model_ptr
335 while (model_ptr->busy_list) {
336 TRACE(trace_model,("waiting for pipeline to empty\n"));
337 model_ptr->nr_stalls_serialize++;
338 model_new_cycle(model_ptr);
340 (void) model_make_busy(model_ptr,
341 model_ptr->timing[index].first_unit,
342 model_ptr->timing[index].issue,
343 model_ptr->timing[index].done);
345 # Wait for a CR to become unbusy
346 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
350 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
353 cr_mask = (1 << cr_var);
354 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
355 TRACE(trace_model,("waiting for CR %d\n", cr_var));
356 model_ptr->nr_stalls_data++;
357 model_new_cycle(model_ptr);
360 # Schedule an instruction that takes 2 integer input registers and produces an output register & possibly sets CR0
361 void::model-function::ppc_insn_int2:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA, signed_word *rB, unsigned Rc
362 registers *cpu_regs = cpu_registers(processor);
363 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
364 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
365 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
366 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RD);
367 model_busy *busy_ptr;
369 if (!WITH_MODEL_ISSUE)
373 if ((model_ptr->int_busy & int_mask) != 0) {
374 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
376 while ((model_ptr->int_busy & int_mask) != 0) {
377 if (WITH_TRACE && ppc_trace[trace_model])
378 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
380 model_ptr->nr_stalls_data++;
381 model_new_cycle(model_ptr);
385 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
386 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
391 const unsigned32 cr_mask = (1 << 0);
393 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
394 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
396 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
397 if (WITH_TRACE && ppc_trace[trace_model])
398 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
400 model_ptr->nr_stalls_data++;
401 model_new_cycle(model_ptr);
405 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
406 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
407 model_make_cr_reg_busy(model_ptr, busy_ptr, 0);
411 # Schedule an instruction that takes 1 integer input registers and produces an output register & possibly sets CR0
412 void::model-function::ppc_insn_int1:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA, unsigned Rc
413 registers *cpu_regs = cpu_registers(processor);
414 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
415 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
416 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RD);
417 model_busy *busy_ptr;
419 if (!WITH_MODEL_ISSUE)
423 if ((model_ptr->int_busy & int_mask) != 0) {
424 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
426 while ((model_ptr->int_busy & int_mask) != 0) {
427 if (WITH_TRACE && ppc_trace[trace_model])
428 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
430 model_ptr->nr_stalls_data++;
431 model_new_cycle(model_ptr);
435 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
436 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
441 const unsigned32 cr_mask = (1 << 0);
443 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
444 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
446 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
447 if (WITH_TRACE && ppc_trace[trace_model])
448 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
450 model_ptr->nr_stalls_data++;
451 model_new_cycle(model_ptr);
455 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
456 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
457 model_make_cr_reg_busy(model_ptr, busy_ptr, 0);
461 # Schedule an instruction that takes no integer input registers and produces an output register & possibly sets CR0
462 void::model-function::ppc_insn_int0:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, unsigned Rc
463 registers *cpu_regs = cpu_registers(processor);
464 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
465 const unsigned32 int_mask = (1 << ppc_RD);
466 model_busy *busy_ptr;
468 if (!WITH_MODEL_ISSUE)
472 while ((model_ptr->int_busy & int_mask) != 0) {
473 if (WITH_TRACE && ppc_trace[trace_model])
474 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
476 model_ptr->nr_stalls_data++;
477 model_new_cycle(model_ptr);
480 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
481 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
486 const unsigned32 cr_mask = (1 << 0);
488 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
489 if (WITH_TRACE && ppc_trace[trace_model])
490 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
492 model_ptr->nr_stalls_data++;
493 model_new_cycle(model_ptr);
496 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
497 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
498 model_make_cr_reg_busy(model_ptr, busy_ptr, 0);
502 # Schedule an instruction that takes 2 integer input registers and produces an output register & updates a second register
503 void::model-function::ppc_insn_int2_update:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA, signed_word *rB
504 if (!WITH_MODEL_ISSUE)
508 registers *cpu_regs = cpu_registers(processor);
509 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
510 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
511 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
512 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RD);
513 model_busy *busy_ptr;
515 if ((model_ptr->int_busy & int_mask) != 0) {
516 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
518 while ((model_ptr->int_busy & int_mask) != 0) {
519 if (WITH_TRACE && ppc_trace[trace_model])
520 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
522 model_ptr->nr_stalls_data++;
523 model_new_cycle(model_ptr);
527 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
528 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
529 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
532 # Schedule an instruction that takes 1 integer input registers and produces an output register & updates the other register
533 void::model-function::ppc_insn_int1_update:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA
534 if (!WITH_MODEL_ISSUE)
538 registers *cpu_regs = cpu_registers(processor);
539 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
540 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
541 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RD);
542 model_busy *busy_ptr;
544 if ((model_ptr->int_busy & int_mask) != 0) {
545 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
547 while ((model_ptr->int_busy & int_mask) != 0) {
548 if (WITH_TRACE && ppc_trace[trace_model])
549 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
551 model_ptr->nr_stalls_data++;
552 model_new_cycle(model_ptr);
556 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
557 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
558 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
561 # Schedule an instruction that takes 2 integer input registers and produces no output register
562 void::model-function::ppc_insn_int2_noout:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rA, signed_word *rB
563 if (!WITH_MODEL_ISSUE)
567 registers *cpu_regs = cpu_registers(processor);
568 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
569 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
570 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB);
572 if ((model_ptr->int_busy & int_mask) != 0) {
573 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
575 while ((model_ptr->int_busy & int_mask) != 0) {
576 if (WITH_TRACE && ppc_trace[trace_model])
577 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
579 model_ptr->nr_stalls_data++;
580 model_new_cycle(model_ptr);
584 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
587 # Schedule an instruction that takes 1 integer input registers and produces no output register
588 void::model-function::ppc_insn_int1_noout:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rA
589 if (!WITH_MODEL_ISSUE)
593 registers *cpu_regs = cpu_registers(processor);
594 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
595 const unsigned32 int_mask = (1 << ppc_RA);
597 if ((model_ptr->int_busy & int_mask) != 0) {
598 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
600 while ((model_ptr->int_busy & int_mask) != 0) {
601 if (WITH_TRACE && ppc_trace[trace_model])
602 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
604 model_ptr->nr_stalls_data++;
605 model_new_cycle(model_ptr);
609 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
612 # Schedule an instruction that takes no input registers and produces no output
613 void::model-function::ppc_insn_int0_noout:itable_index index, cpu *processor, model_data *model_ptr
614 if (!WITH_MODEL_ISSUE)
618 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
621 # Schedule an instruction that takes 2 integer input registers and produces a CR output register
622 void::model-function::ppc_insn_int2_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, signed_word *rA, signed_word *rB
623 if (!WITH_MODEL_ISSUE)
627 registers *cpu_regs = cpu_registers(processor);
628 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
629 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
630 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB);
631 const unsigned32 cr_mask = (1 << CRD);
632 model_busy *busy_ptr;
634 if ((model_ptr->int_busy & int_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->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
638 if (WITH_TRACE && ppc_trace[trace_model])
639 model_trace_busy_p(model_ptr, int_mask, 0, 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_make_cr_reg_busy(model_ptr, busy_ptr, CRD);
650 # Schedule an instruction that takes 1 integer input register and produces a CR output register
651 void::model-function::ppc_insn_int1_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, signed_word *rA
652 if (!WITH_MODEL_ISSUE)
656 registers *cpu_regs = cpu_registers(processor);
657 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
658 const unsigned32 int_mask = (1 << ppc_RA);
659 const unsigned32 cr_mask = (1 << CRD);
660 model_busy *busy_ptr;
662 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_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->cr_fpscr_busy & cr_mask)) {
666 if (WITH_TRACE && ppc_trace[trace_model])
667 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
669 model_ptr->nr_stalls_data++;
670 model_new_cycle(model_ptr);
674 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
675 model_make_cr_reg_busy(model_ptr, busy_ptr, CRD);
678 # Schedule an instruction that takes 3 floating point input registers and produces an output register & possibly sets CR1
679 void::model-function::ppc_insn_fp3:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, unsigned64 *rA, unsigned64 *rB, unsigned64 *rC, unsigned Rc
680 registers *cpu_regs = cpu_registers(processor);
681 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
682 const unsigned ppc_RB = (rB - &cpu_regs->fpr[0]);
683 const unsigned ppc_RC = (rC - &cpu_regs->fpr[0]);
684 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
685 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RC) | (1 << ppc_RD);
686 model_busy *busy_ptr;
688 if (!WITH_MODEL_ISSUE)
692 if ((model_ptr->fp_busy & fp_mask) != 0) {
693 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
695 while ((model_ptr->fp_busy & fp_mask) != 0) {
696 if (WITH_TRACE && ppc_trace[trace_model])
697 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
699 model_ptr->nr_stalls_data++;
700 model_new_cycle(model_ptr);
704 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
705 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
710 const unsigned32 cr_mask = (1 << 1);
711 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
712 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
714 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
715 if (WITH_TRACE && ppc_trace[trace_model])
716 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
718 model_ptr->nr_stalls_data++;
719 model_new_cycle(model_ptr);
723 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
724 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
725 model_make_cr_reg_busy(model_ptr, busy_ptr, 1);
729 # Schedule an instruction that takes 2 floating point input registers and produces an output register & possibly sets CR1
730 void::model-function::ppc_insn_fp2:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, unsigned64 *rA, unsigned64 *rB, unsigned Rc
731 registers *cpu_regs = cpu_registers(processor);
732 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
733 const unsigned ppc_RB = (rB - &cpu_regs->fpr[0]);
734 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
735 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RD);
736 model_busy *busy_ptr;
738 if (!WITH_MODEL_ISSUE)
742 if ((model_ptr->fp_busy & fp_mask) != 0) {
743 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
745 while ((model_ptr->fp_busy & fp_mask) != 0) {
746 if (WITH_TRACE && ppc_trace[trace_model])
747 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
749 model_ptr->nr_stalls_data++;
750 model_new_cycle(model_ptr);
754 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
755 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
759 const unsigned32 cr_mask = (1 << 1);
761 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
762 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
764 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
765 if (WITH_TRACE && ppc_trace[trace_model])
766 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
768 model_ptr->nr_stalls_data++;
769 model_new_cycle(model_ptr);
773 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
774 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
775 model_make_cr_reg_busy(model_ptr, busy_ptr, 1);
778 # Schedule an instruction that takes 1 floating point input registers and produces an output register & possibly sets CR1
779 void::model-function::ppc_insn_fp1:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, unsigned64 *rA, unsigned Rc
780 registers *cpu_regs = cpu_registers(processor);
781 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
782 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
783 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RD);
784 model_busy *busy_ptr;
786 if (!WITH_MODEL_ISSUE)
790 if ((model_ptr->fp_busy & fp_mask) != 0) {
791 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
793 while ((model_ptr->fp_busy & fp_mask) != 0) {
794 if (WITH_TRACE && ppc_trace[trace_model])
795 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
797 model_ptr->nr_stalls_data++;
798 model_new_cycle(model_ptr);
802 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
803 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
807 const unsigned32 cr_mask = (1 << 1);
809 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
810 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
812 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
813 if (WITH_TRACE && ppc_trace[trace_model])
814 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
816 model_ptr->nr_stalls_data++;
817 model_new_cycle(model_ptr);
821 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
822 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
823 model_make_cr_reg_busy(model_ptr, busy_ptr, 1);
826 # Schedule an instruction that takes 1 floating point input register & 2 integer registers and does not produce an output
827 # (or takes 2 integer registers and produces an output in the floating point register)
828 void::model-function::ppc_insn_int2_fp1:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, signed_word *rA, signed_word *rB, int RD_is_output, int RA_is_update
829 if (!WITH_MODEL_ISSUE)
833 registers *cpu_regs = cpu_registers(processor);
834 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
835 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
836 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
837 const unsigned32 int_mask = (1 << ppc_RB) | ((ppc_RA == 0) ? 0 : (1 << ppc_RA));
838 const unsigned32 fp_mask = (1 << ppc_RD);
839 model_busy *busy_ptr;
841 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
842 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
844 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
845 if (WITH_TRACE && ppc_trace[trace_model])
846 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
848 model_ptr->nr_stalls_data++;
849 model_new_cycle(model_ptr);
853 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
855 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
858 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
861 # Schedule an instruction that takes 1 floating point input register & 1 integer register and does not produce an output
862 # (or takes 1 integer register and produces an output in the floating point register)
863 void::model-function::ppc_insn_int1_fp1:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, signed_word *rA, int RD_is_output, int RA_is_update
864 if (!WITH_MODEL_ISSUE)
868 registers *cpu_regs = cpu_registers(processor);
869 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
870 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
871 const unsigned32 int_mask = ((ppc_RA == 0) ? 0 : (1 << ppc_RA));
872 const unsigned32 fp_mask = (1 << ppc_RD);
873 model_busy *busy_ptr;
875 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
876 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
878 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
879 if (WITH_TRACE && ppc_trace[trace_model])
880 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
882 model_ptr->nr_stalls_data++;
883 model_new_cycle(model_ptr);
887 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
889 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
892 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
895 # Schedule an instruction that takes 2 floating input registers and produces a CR output register
896 void::model-function::ppc_insn_fp2_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, unsigned64 *rA, unsigned64 *rB
897 if (!WITH_MODEL_ISSUE)
901 registers *cpu_regs = cpu_registers(processor);
902 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
903 const unsigned ppc_RB = (rB - &cpu_regs->fpr[0]);
904 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RB);
905 const unsigned32 cr_mask = (1 << CRD);
906 model_busy *busy_ptr;
908 if (((model_ptr->fp_busy & fp_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
909 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
911 while (((model_ptr->fp_busy & fp_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
912 if (WITH_TRACE && ppc_trace[trace_model])
913 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
915 model_ptr->nr_stalls_data++;
916 model_new_cycle(model_ptr);
920 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
921 model_make_cr_reg_busy(model_ptr, busy_ptr, CRD);
924 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
925 void::model-function::ppc_insn_from_spr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, unsigned nSPR
926 if (!WITH_MODEL_ISSUE)
930 registers *cpu_regs = cpu_registers(processor);
931 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
932 const unsigned32 int_mask = (1 << ppc_RD);
933 model_busy *busy_ptr;
935 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
936 if (WITH_TRACE && ppc_trace[trace_model])
937 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
939 model_ptr->nr_stalls_data++;
940 model_new_cycle(model_ptr);
943 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
944 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
947 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
948 void::model-function::ppc_insn_to_spr:itable_index index, cpu *processor, model_data *model_ptr, unsigned nSPR, signed_word *rS
949 if (!WITH_MODEL_ISSUE)
953 registers *cpu_regs = cpu_registers(processor);
954 const unsigned ppc_RS = (rS - &cpu_regs->gpr[0]);
955 const unsigned32 int_mask = (1 << ppc_RS);
956 model_busy *busy_ptr;
958 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
959 if (WITH_TRACE && ppc_trace[trace_model])
960 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
962 model_ptr->nr_stalls_data++;
963 model_new_cycle(model_ptr);
966 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
967 model_make_spr_reg_busy(model_ptr, busy_ptr, nSPR);
970 # Schedule a MFCR instruction that moves the CR into an integer regsiter
971 void::model-function::ppc_insn_mfcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD
972 if (!WITH_MODEL_ISSUE)
976 registers *cpu_regs = cpu_registers(processor);
977 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
978 const unsigned32 int_mask = (1 << ppc_RD);
979 const unsigned32 cr_mask = 0xff;
980 model_busy *busy_ptr;
982 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
983 if (WITH_TRACE && ppc_trace[trace_model])
984 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
986 model_ptr->nr_stalls_data++;
987 model_new_cycle(model_ptr);
990 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
991 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
994 # Schedule a MTCR instruction that moves an integer register into the CR
995 void::model-function::ppc_insn_mtcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rT, unsigned FXM
996 if (!WITH_MODEL_ISSUE)
1000 registers *cpu_regs = cpu_registers(processor);
1001 const unsigned ppc_RT = (rT - &cpu_regs->gpr[0]);
1002 const unsigned32 int_mask = (1 << ppc_RT);
1003 const unsigned32 cr_mask = 0xff;
1004 const model_time *normal_time = &model_ptr->timing[index];
1005 static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 };
1006 model_busy *busy_ptr;
1009 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
1010 if (WITH_TRACE && ppc_trace[trace_model])
1011 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
1013 model_ptr->nr_stalls_data++;
1014 model_new_cycle(model_ptr);
1017 /* If only one bit is being moved, use the SCIU, not the MCIU on the 604 */
1018 if (CURRENT_MODEL == MODEL_ppc604 && (FXM & (FXM-1)) == 0) {
1019 normal_time = &ppc604_1bit_time;
1022 busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
1023 for (i = 0; i < 8; i++) {
1024 model_make_cr_reg_busy(model_ptr, busy_ptr, i);
1028 # Convert a BIT32(x) number back into the original number
1029 int::model-internal::ppc_undo_bit32:unsigned bitmask
1030 unsigned u = 0x80000000;
1032 while (u && (u & bitmask) == 0) {
1039 # Schedule an instruction that takes 2 CR input registers and produces an output CR register
1040 void::model-function::ppc_insn_cr2:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned crA_bit, unsigned crB_bit
1041 if (!WITH_MODEL_ISSUE)
1045 const unsigned ppc_CRA = ppc_undo_bit32(crA_bit);
1046 const unsigned ppc_CRB = ppc_undo_bit32(crB_bit);
1047 const unsigned32 cr_mask = (1 << ppc_CRA) | (1 << ppc_CRB) | (1 << crD);
1048 model_busy *busy_ptr;
1050 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
1051 if (WITH_TRACE && ppc_trace[trace_model])
1052 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
1054 model_ptr->nr_stalls_data++;
1055 model_new_cycle(model_ptr);
1058 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1059 model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
1062 # Schedule an instruction that takes 1 CR input registers and produces an output CR register
1063 void::model-function::ppc_insn_cr1:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned CRA
1064 if (!WITH_MODEL_ISSUE)
1068 const unsigned32 cr_mask = (1 << CRA) | (1 << crD);
1069 model_busy *busy_ptr;
1071 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
1072 if (WITH_TRACE && ppc_trace[trace_model])
1073 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
1075 model_ptr->nr_stalls_data++;
1076 model_new_cycle(model_ptr);
1079 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1080 model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
1083 model_data *::model-function::model_create:cpu *processor
1084 model_data *model_ptr = ZALLOC(model_data);
1085 ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
1086 model_ptr->name = model_name[CURRENT_MODEL];
1087 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
1088 model_ptr->processor = processor;
1089 model_ptr->nr_cycles = 1;
1092 void::model-function::model_init:model_data *model_ptr
1094 void::model-function::model_halt:model_data *model_ptr
1095 /* Let pipeline drain */
1096 while (model_ptr->busy_list)
1097 model_new_cycle(model_ptr);
1099 model_print *::model-function::model_mon_info:model_data *model_ptr
1102 ppc_function_unit i;
1103 count_type nr_insns;
1105 head = tail = ZALLOC(model_print);
1106 tail->count = model_ptr->nr_cycles;
1107 tail->name = "cycle";
1108 tail->suffix_plural = "s";
1109 tail->suffix_singular = "";
1111 if (model_ptr->nr_stalls_data) {
1112 tail->next = ZALLOC(model_print);
1114 tail->count = model_ptr->nr_stalls_data;
1115 tail->name = "stall";
1116 tail->suffix_plural = "s waiting for data";
1117 tail->suffix_singular = " waiting for data";
1120 if (model_ptr->nr_stalls_unit) {
1121 tail->next = ZALLOC(model_print);
1123 tail->count = model_ptr->nr_stalls_unit;
1124 tail->name = "stall";
1125 tail->suffix_plural = "s waiting for a function unit";
1126 tail->suffix_singular = " waiting for a function unit";
1129 if (model_ptr->nr_stalls_serialize) {
1130 tail->next = ZALLOC(model_print);
1132 tail->count = model_ptr->nr_stalls_serialize;
1133 tail->name = "stall";
1134 tail->suffix_plural = "s waiting for serialization";
1135 tail->suffix_singular = " waiting for serialization";
1138 if (model_ptr->nr_branches) {
1139 tail->next = ZALLOC(model_print);
1141 tail->count = model_ptr->nr_branches;
1142 tail->name = "branch";
1143 tail->suffix_plural = "es";
1144 tail->suffix_singular = "";
1147 if (model_ptr->nr_branches_fallthrough) {
1148 tail->next = ZALLOC(model_print);
1150 tail->count = model_ptr->nr_branches_fallthrough;
1151 tail->name = "conditional branch";
1152 tail->suffix_plural = "es fell through";
1153 tail->suffix_singular = " fell through";
1156 if (model_ptr->nr_branch_predict_trues) {
1157 tail->next = ZALLOC(model_print);
1159 tail->count = model_ptr->nr_branch_predict_trues;
1160 tail->name = "successful branch prediction";
1161 tail->suffix_plural = "s";
1162 tail->suffix_singular = "";
1165 if (model_ptr->nr_branch_predict_falses) {
1166 tail->next = ZALLOC(model_print);
1168 tail->count = model_ptr->nr_branch_predict_falses;
1169 tail->name = "unsuccessful branch prediction";
1170 tail->suffix_plural = "s";
1171 tail->suffix_singular = "";
1175 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
1176 if (model_ptr->nr_units[i]) {
1177 nr_insns += model_ptr->nr_units[i];
1178 tail->next = ZALLOC(model_print);
1180 tail->count = model_ptr->nr_units[i];
1181 tail->name = ppc_function_unit_name[i];
1182 tail->suffix_plural = "s";
1183 tail->suffix_singular = "";
1187 tail->next = ZALLOC(model_print);
1189 tail->count = nr_insns;
1190 tail->name = "instruction";
1191 tail->suffix_plural = "s that were accounted for in timing info";
1192 tail->suffix_singular = " that was accounted for in timing info";
1194 tail->next = (model_print *)0;
1197 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
1199 model_print *next = ptr->next;
1204 void::model-function::model_branches:model_data *model_ptr, int failed
1205 model_ptr->nr_units[PPC_UNIT_BPU]++;
1207 model_ptr->nr_branches_fallthrough++;
1209 model_ptr->nr_branches++;
1210 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
1212 void::model-function::model_branch_predict:model_data *model_ptr, int success
1214 model_ptr->nr_branch_predict_trues++;
1216 model_ptr->nr_branch_predict_falses++;
1219 # The following (illegal) instruction is `known' by gen and is
1220 # called when ever an illegal instruction is encountered
1222 program_interrupt(processor, cia,
1223 illegal_instruction_program_interrupt);
1227 # The following (floating point unavailable) instruction is `known' by gen
1228 # and is called when ever an a floating point instruction is to be
1229 # executed but floating point is make unavailable by the MSR
1230 ::internal::floating_point_unavailable
1231 floating_point_unavailable_interrupt(processor, cia);
1236 # Floating point support functions
1239 # Convert 32bit single to 64bit double
1240 unsigned64::function::DOUBLE:unsigned32 WORD
1242 if (EXTRACTED32(WORD, 1, 8) > 0
1243 && EXTRACTED32(WORD, 1, 8) < 255) {
1244 /* normalized operand */
1245 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
1246 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
1247 | INSERTED64(not_word_1_1, 2, 2)
1248 | INSERTED64(not_word_1_1, 3, 3)
1249 | INSERTED64(not_word_1_1, 4, 4)
1250 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
1252 else if (EXTRACTED32(WORD, 1, 8) == 0
1253 && EXTRACTED32(WORD, 9, 31) != 0) {
1254 /* denormalized operand */
1255 int sign = EXTRACTED32(WORD, 0, 0);
1257 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
1258 /* normalize the operand */
1259 while (MASKED64(frac, 0, 0) == 0) {
1263 FRT = (INSERTED64(sign, 0, 0)
1264 | INSERTED64(exp + 1023, 1, 11)
1265 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
1267 else if (EXTRACTED32(WORD, 1, 8) == 255
1268 || EXTRACTED32(WORD, 1, 31) == 0) {
1269 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
1270 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
1271 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
1272 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
1273 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
1276 error("DOUBLE - unknown case\n");
1281 # Convert 64bit single to 32bit double
1282 unsigned32::function::SINGLE:unsigned64 FRS
1284 if (EXTRACTED64(FRS, 1, 11) > 896
1285 || EXTRACTED64(FRS, 1, 63) == 0) {
1286 /* no denormalization required (includes Zero/Infinity/NaN) */
1287 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
1288 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
1290 else if (874 <= EXTRACTED64(FRS, 1, 11)
1291 && EXTRACTED64(FRS, 1, 11) <= 896) {
1292 /* denormalization required */
1293 int sign = EXTRACTED64(FRS, 0, 0);
1294 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
1295 unsigned64 frac = (BIT64(0)
1296 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
1297 /* denormalize the operand */
1298 while (exp < -126) {
1299 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1302 WORD = (INSERTED32(sign, 0, 0)
1303 | INSERTED32(0x00, 1, 8)
1304 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
1307 WORD = 0x0; /* ??? */
1312 # round 64bit double to 64bit but single
1313 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
1314 /* comparisons ignore u bits */
1317 int lsb = EXTRACTED64(*frac_grx, 23, 23);
1318 int gbit = EXTRACTED64(*frac_grx, 24, 24);
1319 int rbit = EXTRACTED64(*frac_grx, 25, 25);
1320 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
1321 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
1322 if (lsb == 1 && gbit == 1) inc = 1;
1323 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1324 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1326 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
1327 if (sign == 0 && gbit == 1) inc = 1;
1328 if (sign == 0 && rbit == 1) inc = 1;
1329 if (sign == 0 && xbit == 1) inc = 1;
1331 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
1332 if (sign == 1 && gbit == 1) inc = 1;
1333 if (sign == 1 && rbit == 1) inc = 1;
1334 if (sign == 1 && xbit == 1) inc = 1;
1336 /* work out addition in low 25 bits of out */
1337 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
1338 *frac_grx = INSERTED64(out, 0, 23);
1339 if (out & BIT64(64 - 23 - 1 - 1)) {
1340 *frac_grx = (BIT64(0) |
1341 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
1344 /* frac_grx[24:52] = 0 already */
1346 FPSCR_SET_FI(gbit || rbit || xbit);
1350 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
1352 if (round_mode == fpscr_rn_round_to_nearest) {
1353 if (*frac64 == 1 && gbit == 1) inc = 1;
1354 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
1355 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
1357 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1358 if (sign == 0 && gbit == 1) inc = 1;
1359 if (sign == 0 && rbit == 1) inc = 1;
1360 if (sign == 0 && xbit == 1) inc = 1;
1362 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1363 if (sign == 1 && gbit == 1) inc = 1;
1364 if (sign == 1 && rbit == 1) inc = 1;
1365 if (sign == 1 && xbit == 1) inc = 1;
1367 /* frac[0:64] = frac[0:64} + inc */
1368 *frac += (*frac64 && inc ? 1 : 0);
1369 *frac64 = (*frac64 + inc) & 0x1;
1371 FPSCR_SET_FI(gbit | rbit | xbit);
1374 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
1377 int lsb = EXTRACTED64(*frac, 52, 52);
1378 int gbit = EXTRACTED64(*frac, 53, 53);
1379 int rbit = EXTRACTED64(*frac, 54, 54);
1380 int xbit = EXTRACTED64(*frac, 55, 55);
1381 if (round_mode == fpscr_rn_round_to_nearest) {
1382 if (lsb == 1 && gbit == 1) inc = 1;
1383 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1384 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1386 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1387 if (sign == 0 && gbit == 1) inc = 1;
1388 if (sign == 0 && rbit == 1) inc = 1;
1389 if (sign == 0 && xbit == 1) inc = 1;
1391 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1392 if (sign == 1 && gbit == 1) inc = 1;
1393 if (sign == 1 && rbit == 1) inc = 1;
1394 if (sign == 1 && xbit == 1) inc = 1;
1396 /* frac//carry_out = frac + inc */
1397 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1398 carry_out = EXTRACTED64(*frac, 0, 0);
1400 if (carry_out == 1) *exp = *exp + 1;
1402 FPSCR_SET_FI(gbit | rbit | xbit);
1403 FPSCR_SET_XX(FPSCR & fpscr_fi);
1406 # conversion of FP to integer
1407 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
1410 unsigned64 frac = 0;
1415 int sign = EXTRACTED64(frb, 0, 0);
1416 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1417 goto Infinity_Operand;
1418 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1420 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1422 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
1423 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1424 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1425 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1426 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1429 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1430 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1433 gbit = 0, rbit = 0, xbit = 0;
1434 for (i = 1; i <= 63 - exp; i++) {
1438 frac64 = EXTRACTED64(frac, 63, 63);
1439 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1441 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1442 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1445 frac += (frac64 ? 1 : 0);
1446 frac64 = (frac64 + 1) & 0x1;
1448 if (tgt_precision == 32 /* can ignore frac64 in compare */
1449 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1451 if (tgt_precision == 64 /* can ignore frac64 in compare */
1452 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1454 if (tgt_precision == 32 /* can ignore frac64 in compare */
1455 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1457 if (tgt_precision == 64 /* can ignore frac64 in compare */
1458 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1460 FPSCR_SET_XX(FPSCR & fpscr_fi);
1461 if (tgt_precision == 32)
1462 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1463 if (tgt_precision == 64)
1464 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1465 /*FPSCR[fprf] = undefined */
1471 FPSCR_OR_VX(fpscr_vxcvi);
1472 if ((FPSCR & fpscr_ve) == 0) {
1473 if (tgt_precision == 32) {
1474 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1475 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1478 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1479 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1481 /* FPSCR[FPRF] = undefined */
1488 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1489 if ((FPSCR & fpscr_ve) == 0) {
1490 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1491 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1492 /* FPSCR[fprf] = undefined */
1499 FPSCR_OR_VX(fpscr_vxcvi);
1500 if ((FPSCR & fpscr_ve) == 0) {
1501 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1502 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1503 /* FPSCR[fprf] = undefined */
1510 FPSCR_OR_VX(fpscr_vxcvi);
1511 if ((FPSCR & fpscr_ve) == 0) {
1512 if (tgt_precision == 32) {
1513 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1514 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1517 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1518 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1520 /* FPSCR[fprf] = undefined */
1526 # extract out raw fields of a FP number
1527 int::function::sign:unsigned64 FRS
1528 return (MASKED64(FRS, 0, 0)
1531 int::function::biased_exp:unsigned64 frs, int single
1533 return EXTRACTED64(frs, 1, 8);
1535 return EXTRACTED64(frs, 1, 11);
1536 unsigned64::function::fraction:unsigned64 frs, int single
1538 return EXTRACTED64(frs, 9, 31);
1540 return EXTRACTED64(frs, 12, 63);
1542 # a number?, each of the below return +1 or -1 (based on sign bit)
1544 int::function::is_nor:unsigned64 frs, int single
1545 int exp = biased_exp(frs, single);
1547 && exp <= (single ? 254 : 2046));
1548 int::function::is_zero:unsigned64 FRS
1549 return (MASKED64(FRS, 1, 63) == 0
1552 int::function::is_den:unsigned64 frs, int single
1553 int exp = biased_exp(frs, single);
1554 unsigned64 frac = fraction(frs, single);
1555 return (exp == 0 && frac != 0
1558 int::function::is_inf:unsigned64 frs, int single
1559 int exp = biased_exp(frs, single);
1560 int frac = fraction(frs, single);
1561 return (exp == (single ? 255 : 2047) && frac == 0
1564 int::function::is_NaN:unsigned64 frs, int single
1565 int exp = biased_exp(frs, single);
1566 int frac = fraction(frs, single);
1567 return (exp == (single ? 255 : 2047) && frac != 0
1570 int::function::is_SNaN:unsigned64 frs, int single
1571 return (is_NaN(frs, single)
1572 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1575 int::function::is_QNaN:unsigned64 frs, int single
1576 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1577 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1578 return *(double*)fra < *(double*)frb;
1579 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1580 return *(double*)fra > *(double*)frb;
1581 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1582 return *(double*)fra == *(double*)frb;
1585 # which quiet nan should become the result
1586 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1588 if (is_NaN(fra, single))
1590 else if (is_NaN(frb, single))
1591 if (instruction_is_frsp)
1592 frt = MASKED64(frb, 0, 34);
1595 else if (is_NaN(frc, single))
1597 else if (generate_qnan)
1598 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1600 error("select_qnan - default reached\n");
1604 # detect invalid operation
1605 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1607 if ((check & fpscr_vxsnan)
1608 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1609 FPSCR_OR_VX(fpscr_vxsnan);
1612 if ((check & fpscr_vxisi)
1613 && (is_inf(fra, single) && is_inf(frb, single))
1614 && ((negate && sign(fra) != sign(frb))
1615 || (!negate && sign(fra) == sign(frb)))) {
1616 /*FIXME: don't handle inf-inf VS inf+-inf */
1617 FPSCR_OR_VX(fpscr_vxisi);
1620 if ((check & fpscr_vxidi)
1621 && (is_inf(fra, single) && is_inf(frb, single))) {
1622 FPSCR_OR_VX(fpscr_vxidi);
1625 if ((check & fpscr_vxzdz)
1626 && (is_zero(fra) && is_zero(frb))) {
1627 FPSCR_OR_VX(fpscr_vxzdz);
1630 if ((check & fpscr_vximz)
1631 && (is_zero(fra) && is_inf(frb, single))) {
1632 FPSCR_OR_VX(fpscr_vximz);
1635 if ((check & fpscr_vxvc)
1636 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1637 FPSCR_OR_VX(fpscr_vxvc);
1640 if ((check & fpscr_vxsoft)) {
1641 FPSCR_OR_VX(fpscr_vxsoft);
1644 if ((check & fpscr_vxsqrt)
1646 FPSCR_OR_VX(fpscr_vxsqrt);
1649 /* if ((check && fpscr_vxcvi) {
1650 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1651 FPSCR_OR_VX(fpscr_vxcvi);
1661 # handle case of invalid operation
1662 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
1663 if (FPSCR & fpscr_ve) {
1664 /* invalid operation exception enabled */
1668 /* fpscr_FPRF unchanged */
1671 /* invalid operation exception disabled */
1672 if (instruction_is_convert_to_64bit) {
1675 else if (instruction_is_convert_to_32bit) {
1678 else { /* arrith, frsp */
1679 *frt = select_qnan(fra, frb, frc,
1680 instruction_is_frsp, 0/*generate*/, single);
1683 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1691 # I.2.4.1 Branch Instructions
1693 0.18,6.LI,30.AA,31.LK:I:t::Branch
1694 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1695 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1696 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1697 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1698 if (AA) NIA = IEA(EXTS(LI_0b00));
1699 else NIA = IEA(CIA + EXTS(LI_0b00));
1700 if (LK) LR = (spreg)CIA+4;
1701 model_branches(cpu_model(processor), 1);
1703 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
1704 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1705 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1706 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1707 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1708 int M, ctr_ok, cond_ok, succeed;
1710 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1711 if (is_64bit_implementation && is_64bit_mode) M = 0;
1713 if (!BO{2}) CTR = CTR - 1;
1714 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1715 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1716 if (ctr_ok && cond_ok) {
1717 if (AA) NIA = IEA(EXTS(BD_0b00));
1718 else NIA = IEA(CIA + EXTS(BD_0b00));
1723 if (LK) LR = (spreg)IEA(CIA + 4);
1724 model_branches(cpu_model(processor), succeed);
1727 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1728 reverse = EXTS(BD_0b00) < 0;
1729 } else { /* branch prediction bit not set */
1730 reverse = EXTS(BD_0b00) >= 0;
1732 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1735 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
1736 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1737 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1738 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1739 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1740 int M, ctr_ok, cond_ok, succeed;
1741 if (is_64bit_implementation && is_64bit_mode) M = 0;
1744 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1745 if (!BO{2}) CTR = CTR - 1;
1746 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1747 cond_ok = BO{0} || (CR{BI} == BO{1});
1748 if (ctr_ok && cond_ok) {
1754 if (LK) LR = (spreg)IEA(CIA + 4);
1755 model_branches(cpu_model(processor), succeed);
1757 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1759 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
1760 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1761 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1762 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1763 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1764 int cond_ok, succeed;
1766 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1767 cond_ok = BO{0} || (CR{BI} == BO{1});
1769 NIA = IEA(CTR_0b00);
1774 if (LK) LR = (spreg)IEA(CIA + 4);
1775 model_branches(cpu_model(processor), succeed);
1777 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1780 # I.2.4.2 System Call Instruction
1782 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
1783 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1784 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1785 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1786 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1787 model_serialize(my_index, cpu_model(processor));
1788 system_call_interrupt(processor, cia);
1791 # I.2.4.3 Condition Register Logical Instructions
1793 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1794 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1795 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1796 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1797 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1798 BLIT32(CR, BT, CR{BA} && CR{BB});
1799 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1801 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1802 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1803 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1804 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1805 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1806 BLIT32(CR, BT, CR{BA} || CR{BB});
1807 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1809 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1810 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1811 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1812 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1813 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1814 BLIT32(CR, BT, CR{BA} != CR{BB});
1815 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1817 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1818 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1819 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1820 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1821 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1822 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1823 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1825 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1826 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1827 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1828 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1829 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1830 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1831 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1833 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1834 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1835 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1836 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1837 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1838 BLIT32(CR, BT, CR{BA} == CR{BB});
1839 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1841 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1842 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1843 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1844 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1845 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1846 BLIT32(CR, BT, CR{BA} && !CR{BB});
1847 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1849 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1850 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1851 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1852 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1853 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1854 BLIT32(CR, BT, CR{BA} || !CR{BB});
1855 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1858 # I.2.4.4 Condition Register Field Instruction
1860 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1861 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1862 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1863 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1864 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1865 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1866 ppc_insn_cr1(my_index, processor, cpu_model(processor), BF, BFA);
1870 # I.3.3.2 Fixed-Point Load Instructions
1873 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1874 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1875 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1876 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1877 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1883 *rT = MEM(unsigned, EA, 1);
1885 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1887 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
1890 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1891 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1892 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1893 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1894 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1900 *rT = MEM(unsigned, EA, 1);
1902 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
1904 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
1906 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1907 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1908 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1909 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1910 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1912 if (RA == 0 || RA == RT)
1913 program_interrupt(processor, cia,
1914 illegal_instruction_program_interrupt);
1916 *rT = MEM(unsigned, EA, 1);
1918 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
1920 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1921 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1922 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1923 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1924 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1926 if (RA == 0 || RA == RT)
1927 program_interrupt(processor, cia,
1928 illegal_instruction_program_interrupt);
1930 *rT = MEM(unsigned, EA, 1);
1932 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
1934 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1935 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1936 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1937 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1938 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1944 *rT = MEM(unsigned, EA, 2);
1946 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1948 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
1950 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1951 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1952 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1953 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1954 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1960 *rT = MEM(unsigned, EA, 2);
1962 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
1964 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
1966 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1967 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1968 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1969 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1970 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1972 if (RA == 0 || RA == RT)
1973 program_interrupt(processor, cia,
1974 illegal_instruction_program_interrupt);
1976 *rT = MEM(unsigned, EA, 2);
1978 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
1980 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1981 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1982 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1983 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1984 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1986 if (RA == 0 || RA == RT)
1987 program_interrupt(processor, cia,
1988 illegal_instruction_program_interrupt);
1990 *rT = MEM(unsigned, EA, 2);
1992 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
1994 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1995 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1996 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1997 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1998 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2004 *rT = MEM(signed, EA, 2);
2006 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2008 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2010 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
2011 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 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, 2, 0
2020 *rT = MEM(signed, EA, 2);
2022 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2024 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2026 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
2027 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2028 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2029 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2030 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2032 if (RA == 0 || RA == RT)
2033 program_interrupt(processor, cia,
2034 illegal_instruction_program_interrupt);
2036 *rT = MEM(signed, EA, 2);
2037 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
2039 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
2040 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2041 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2042 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2043 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2045 if (RA == 0 || RA == RT)
2046 program_interrupt(processor, cia,
2047 illegal_instruction_program_interrupt);
2049 *rT = MEM(signed, EA, 2);
2051 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
2053 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
2054 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2055 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2056 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2057 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2063 *rT = MEM(unsigned, EA, 4);
2065 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2067 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2069 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
2070 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2071 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2072 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2073 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2079 *rT = MEM(unsigned, EA, 4);
2081 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2083 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2085 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
2086 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2087 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2088 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2089 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2091 if (RA == 0 || RA == RT)
2092 program_interrupt(processor, cia,
2093 illegal_instruction_program_interrupt);
2095 *rT = MEM(unsigned, EA, 4);
2097 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
2099 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
2100 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2101 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2102 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2103 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2105 if (RA == 0 || RA == RT)
2106 program_interrupt(processor, cia,
2107 illegal_instruction_program_interrupt);
2109 *rT = MEM(unsigned, EA, 4);
2111 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
2113 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
2116 # if (RA == 0) b = 0;
2118 # EA = b + EXTS(DS_0b00);
2119 # *rT = MEM(signed, EA, 4);
2121 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
2124 # if (RA == 0) b = 0;
2127 # *rT = MEM(signed, EA, 4);
2129 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
2131 # if (RA == 0 || RA == RT)
2132 # program_interrupt(processor, cia
2133 # illegal_instruction_program_interrupt);
2135 # *rT = MEM(signed, EA, 4);
2138 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
2141 # if (RA == 0) b = 0;
2143 # EA = b + EXTS(DS_0b00);
2144 # *rT = MEM(unsigned, EA, 8);
2146 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
2149 # if (RA == 0) b = 0;
2152 # *rT = MEM(unsigned, EA, 8);
2154 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
2156 # if (RA == 0 || RA == RT)
2157 # program_interrupt(processor, cia
2158 # illegal_instruction_program_interrupt);
2159 # EA = *rA + EXTS(DS_0b00);
2160 # *rT = MEM(unsigned, EA, 8);
2163 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
2165 # if (RA == 0 || RA == RT)
2166 # program_interrupt(processor, cia
2167 # illegal_instruction_program_interrupt);
2169 # *rT = MEM(unsigned, EA, 8);
2175 # I.3.3.3 Fixed-Point Store Instructions
2178 0.38,6.RS,11.RA,16.D:D:::Store Byte
2179 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2180 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2181 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2182 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2190 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
2192 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
2194 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
2195 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2196 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2197 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2198 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2206 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2208 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2210 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
2211 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2212 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2213 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2214 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2217 program_interrupt(processor, cia,
2218 illegal_instruction_program_interrupt);
2222 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
2224 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
2225 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2226 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2227 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2228 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2231 program_interrupt(processor, cia,
2232 illegal_instruction_program_interrupt);
2236 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
2238 0.44,6.RS,11.RA,16.D:D:::Store Half Word
2239 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2240 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2241 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2242 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2250 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
2252 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
2254 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
2255 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2256 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2257 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2258 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2266 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2268 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2270 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
2271 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2272 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2273 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2274 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2277 program_interrupt(processor, cia,
2278 illegal_instruction_program_interrupt);
2282 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
2284 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
2285 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2286 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2287 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2288 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2291 program_interrupt(processor, cia,
2292 illegal_instruction_program_interrupt);
2296 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
2298 0.36,6.RS,11.RA,16.D:D:::Store Word
2299 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2300 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2301 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2302 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2310 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
2312 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
2314 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
2315 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2316 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2317 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2318 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2326 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2328 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2330 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
2331 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2332 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2333 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2334 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2337 program_interrupt(processor, cia,
2338 illegal_instruction_program_interrupt);
2342 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
2344 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
2345 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2346 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2347 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2348 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2351 program_interrupt(processor, cia,
2352 illegal_instruction_program_interrupt);
2356 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
2358 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2361 # if (RA == 0) b = 0;
2363 # EA = b + EXTS(DS_0b00);
2364 # STORE(EA, 8, *rS);
2365 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2368 # if (RA == 0) b = 0;
2371 # STORE(EA, 8, *rS);
2372 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2375 # program_interrupt(processor, cia
2376 # illegal_instruction_program_interrupt);
2377 # EA = *rA + EXTS(DS_0b00);
2378 # STORE(EA, 8, *rS);
2380 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2383 # program_interrupt(processor, cia
2384 # illegal_instruction_program_interrupt);
2386 # STORE(EA, 8, *rS);
2391 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2394 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2395 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2396 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2397 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2398 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2404 *rT = SWAP_2(MEM(unsigned, EA, 2));
2406 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2408 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2410 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2411 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2412 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2413 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2414 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2420 *rT = SWAP_4(MEM(unsigned, EA, 4));
2422 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2424 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2426 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2427 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2428 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2429 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2430 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2436 STORE(EA, 2, SWAP_2(*rS));
2438 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2440 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2442 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2443 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2444 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2445 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2446 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2452 STORE(EA, 4, SWAP_4(*rS));
2454 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2456 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2460 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2463 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
2465 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2469 # I.3.3.6 Fixed-Point Move Assist Instructions
2472 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
2474 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2476 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
2478 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2482 # I.3.3.7 Storage Synchronization Instructions
2484 # HACK: Rather than monitor addresses looking for a reason
2485 # to cancel a reservation. This code instead keeps
2486 # a copy of the data read from memory. Before performing
2487 # a store, the memory area is checked to see if it has
2489 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2490 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2491 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2492 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2493 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2500 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2501 RESERVE_DATA = MEM(unsigned, EA, 4);
2504 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2511 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2512 RESERVE_DATA = MEM(unsigned, EA, 8);
2515 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2516 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2517 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2518 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2519 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2526 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2527 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2529 CR_SET_XER_SO(0, cr_i_zero);
2532 /* ment to randomly to store, we never do! */
2533 CR_SET_XER_SO(0, 0);
2538 CR_SET_XER_SO(0, 0);
2540 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2547 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2548 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2550 CR_SET_XER_SO(0, cr_i_zero);
2553 /* ment to randomly to store, we never do */
2554 CR_SET_XER_SO(0, 0);
2559 CR_SET_XER_SO(0, 0);
2562 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2563 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2564 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2565 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2566 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2571 # I.3.3.9 Fixed-Point Arithmetic Instructions
2574 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
2575 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2576 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2577 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2578 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2581 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2584 *rT = *rA + EXTS(SI);
2585 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2588 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
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_SRU, 1, 1, 0
2592 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2594 *rT = EXTS(SI) << 16;
2595 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2598 *rT = *rA + (EXTS(SI) << 16);
2599 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2602 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2603 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2604 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2605 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2606 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2609 ALU_END(*rT, 0/*CA*/, OE, Rc);
2610 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2612 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2613 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2614 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2615 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2616 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2621 ALU_END(*rT, 0/*CA*/, OE, Rc);
2622 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2624 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2625 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2626 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2627 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2628 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2631 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2632 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2634 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
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*/, 0/*OE*/, 1/*Rc*/);
2642 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 1/*Rc*/);
2644 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
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
2653 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2654 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2656 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2657 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2658 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2659 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2660 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2663 ALU_END(*rT, 1/*CA*/, OE, Rc);
2664 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2666 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2667 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2668 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2669 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2670 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2671 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2676 ALU_END(*rT, 1/*CA*/, OE, Rc);
2677 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2679 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2680 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2681 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2682 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2683 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2687 ALU_END(*rT, 1/*CA*/, OE, Rc);
2688 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2690 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2691 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2692 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2693 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2694 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2699 ALU_END(*rT, 1/*CA*/, OE, Rc);
2700 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2702 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2703 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2704 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2705 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2706 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2710 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2712 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2713 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2714 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2715 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2716 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2721 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2723 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2724 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2725 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2726 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2727 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2730 ALU_END(*rT, 1/*CA*/, OE, Rc);
2731 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2733 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2734 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2735 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2736 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2737 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2741 ALU_END(*rT, 1/*CA*/, OE, Rc);
2742 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2744 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2745 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2746 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2747 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2748 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2752 ALU_END(*rT,0/*CA*/,OE,Rc);
2753 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2755 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2756 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2757 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2758 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2759 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2760 signed_word prod = *rA * EXTS(SI);
2762 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2764 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2766 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2767 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2768 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2769 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2770 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2771 signed64 a = (signed32)(*rA);
2772 signed64 b = (signed32)(*rB);
2773 signed64 prod = a * b;
2774 signed_word t = prod;
2776 if (t != prod && OE)
2777 XER |= (xer_overflow | xer_summary_overflow);
2778 CR0_COMPARE(t, 0, Rc);
2779 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2781 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2783 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2784 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2785 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2786 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2787 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2788 signed64 a = (signed32)(*rA);
2789 signed64 b = (signed32)(*rB);
2790 signed64 prod = a * b;
2791 signed_word t = EXTRACTED64(prod, 0, 31);
2793 CR0_COMPARE(t, 0, Rc);
2794 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2796 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2798 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2799 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2800 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2801 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2802 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2803 unsigned64 a = (unsigned32)(*rA);
2804 unsigned64 b = (unsigned32)(*rB);
2805 unsigned64 prod = a * b;
2806 signed_word t = EXTRACTED64(prod, 0, 31);
2808 CR0_COMPARE(t, 0, Rc);
2809 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2811 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2813 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2814 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2815 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2816 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2817 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2818 signed64 dividend = (signed32)(*rA);
2819 signed64 divisor = (signed32)(*rB);
2820 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2821 || (dividend == 0x80000000 && divisor == -1)) {
2823 XER |= (xer_overflow | xer_summary_overflow);
2824 CR0_COMPARE(0, 0, Rc);
2827 signed64 quotent = dividend / divisor;
2829 CR0_COMPARE((signed_word)quotent, 0, Rc);
2831 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2833 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2835 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2836 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2837 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2838 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2839 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2840 unsigned64 dividend = (unsigned32)(*rA);
2841 unsigned64 divisor = (unsigned32)(*rB);
2844 XER |= (xer_overflow | xer_summary_overflow);
2845 CR0_COMPARE(0, 0, Rc);
2848 unsigned64 quotent = dividend / divisor;
2850 CR0_COMPARE((signed_word)quotent, 0, Rc);
2852 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2856 # I.3.3.10 Fixed-Point Compare Instructions
2859 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2860 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2861 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2862 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2863 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2864 if (!is_64bit_mode && L)
2865 program_interrupt(processor, cia,
2866 illegal_instruction_program_interrupt);
2869 signed_word b = EXTS(SI);
2874 CR_COMPARE(BF, a, b);
2876 ppc_insn_int1_cr(my_index, processor, cpu_model(processor), BF, rA);
2878 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2879 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2880 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2881 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2882 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2883 if (!is_64bit_mode && L)
2884 program_interrupt(processor, cia,
2885 illegal_instruction_program_interrupt);
2897 CR_COMPARE(BF, a, b);
2899 ppc_insn_int2_cr(my_index, processor, cpu_model(processor), BF, rA, rB);
2901 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2902 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2903 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2904 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2905 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2906 if (!is_64bit_mode && L)
2907 program_interrupt(processor, cia,
2908 illegal_instruction_program_interrupt);
2911 unsigned_word b = UI;
2913 a = MASKED(*rA, 32, 63);
2916 CR_COMPARE(BF, a, b);
2918 ppc_insn_int1_cr(my_index, processor, cpu_model(processor), BF, rA);
2920 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2921 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2922 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2923 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2924 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2925 if (!is_64bit_mode && L)
2926 program_interrupt(processor, cia,
2927 illegal_instruction_program_interrupt);
2932 a = MASKED(*rA, 32, 63);
2933 b = MASKED(*rB, 32, 63);
2939 CR_COMPARE(BF, a, b);
2941 ppc_insn_int2_cr(my_index, processor, cpu_model(processor), BF, rA, rB);
2945 # I.3.3.11 Fixed-Point Trap Instructions
2948 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2950 program_interrupt(processor, cia,
2951 illegal_instruction_program_interrupt);
2953 signed_word a = *rA;
2954 signed_word b = EXTS(SI);
2955 if ((a < b && TO{0})
2957 || (a == b && TO{2})
2958 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2959 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2961 program_interrupt(processor, cia,
2962 trap_program_interrupt);
2965 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2966 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2967 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2968 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2969 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2970 signed_word a = EXTENDED(*rA);
2971 signed_word b = EXTS(SI);
2972 if ((a < b && TO{0})
2974 || (a == b && TO{2})
2975 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2976 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2978 program_interrupt(processor, cia,
2979 trap_program_interrupt);
2981 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2983 program_interrupt(processor, cia,
2984 illegal_instruction_program_interrupt);
2986 signed_word a = *rA;
2987 signed_word b = *rB;
2988 if ((a < b && TO{0})
2990 || (a == b && TO{2})
2991 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2992 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2994 program_interrupt(processor, cia,
2995 trap_program_interrupt);
2998 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2999 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3000 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3001 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3002 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3003 signed_word a = EXTENDED(*rA);
3004 signed_word b = EXTENDED(*rB);
3005 if (TO == 12 && rA == rB) {
3006 ITRACE(trace_breakpoint, ("breakpoint\n"));
3007 cpu_halt(processor, cia, was_trap, 0);
3009 else if ((a < b && TO{0})
3011 || (a == b && TO{2})
3012 || ((unsigned_word)a < (unsigned_word)b && TO{3})
3013 || ((unsigned_word)a > (unsigned_word)b && TO{4})
3015 program_interrupt(processor, cia,
3016 trap_program_interrupt);
3019 # I.3.3.12 Fixed-Point Logical Instructions
3022 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
3023 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3024 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3025 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3026 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3028 CR0_COMPARE(*rA, 0, 1/*Rc*/);
3029 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 1/*Rc*/);
3031 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
3032 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3033 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3034 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3035 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3036 *rA = *rS & (UI << 16);
3037 CR0_COMPARE(*rA, 0, 1/*Rc*/);
3038 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 1/*Rc*/);
3040 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
3041 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3042 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3043 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3044 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3046 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3048 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
3049 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3050 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3051 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3052 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3053 *rA = *rS | (UI << 16);
3054 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3056 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
3057 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3058 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3059 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3060 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3062 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3064 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
3065 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3066 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3067 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3068 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3069 *rA = *rS ^ (UI << 16);
3070 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3072 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
3073 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3074 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3075 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3076 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3078 CR0_COMPARE(*rA, 0, Rc);
3079 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3081 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
3082 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3083 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3084 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3085 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3087 CR0_COMPARE(*rA, 0, Rc);
3088 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3090 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
3091 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3092 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3093 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3094 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3096 CR0_COMPARE(*rA, 0, Rc);
3097 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3099 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
3100 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3101 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3102 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3103 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3105 CR0_COMPARE(*rA, 0, Rc);
3106 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3108 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
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 CR0_COMPARE(*rA, 0, Rc);
3115 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3117 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
3118 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3119 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3120 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3121 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3122 # *rA = ~(*rS ^ *rB); /* A === B */
3123 # CR0_COMPARE(*rA, 0, Rc);
3125 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
3126 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3127 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3128 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3129 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3131 CR0_COMPARE(*rA, 0, Rc);
3132 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3134 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
3135 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3136 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3137 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3138 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3140 CR0_COMPARE(*rA, 0, Rc);
3141 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3143 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
3144 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3145 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3146 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3147 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3148 *rA = (signed_word)(signed8)*rS;
3149 CR0_COMPARE(*rA, 0, Rc);
3150 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3152 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
3153 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3154 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3155 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3156 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3157 *rA = (signed_word)(signed16)*rS;
3158 CR0_COMPARE(*rA, 0, Rc);
3159 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3161 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
3162 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3163 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3164 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3165 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3166 # *rA = (signed_word)(signed32)*rS;
3167 # CR0_COMPARE(*rA, 0, Rc);
3169 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
3171 # unsigned64 mask = BIT64(0);
3172 # unsigned64 source = *rS;
3173 # while (!(source & mask) && mask != 0) {
3178 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3180 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
3181 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3182 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3183 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3184 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3186 unsigned32 mask = BIT32(0);
3187 unsigned32 source = *rS;
3188 while (!(source & mask) && mask != 0) {
3193 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3197 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
3200 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
3201 # long n = (sh_5 << 4) | sh_0_4;
3202 # unsigned_word r = ROTL64(*rS, n);
3203 # long b = (mb_5 << 4) | mb_0_4;
3204 # unsigned_word m = MASK(b, 63);
3205 # signed_word result = r & m;
3207 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3209 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
3210 # long n = (sh_5 << 4) | sh_0_4;
3211 # unsigned_word r = ROTL64(*rS, n);
3212 # long e = (me_5 << 4) | me_0_4;
3213 # unsigned_word m = MASK(0, e);
3214 # signed_word result = r & m;
3216 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3218 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
3219 # long n = (sh_5 << 4) | sh_0_4;
3220 # unsigned_word r = ROTL64(*rS, n);
3221 # long b = (mb_5 << 4) | mb_0_4;
3222 # unsigned_word m = MASK(0, (64-n));
3223 # signed_word result = r & m;
3225 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3227 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
3228 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3229 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3230 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3231 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3234 unsigned32 r = ROTL32(s, n);
3235 unsigned32 m = MASK(MB+32, ME+32);
3236 signed_word result = r & m;
3238 CR0_COMPARE(result, 0, Rc);
3240 ("n=%d, s=0x%x, r=0x%x, m=0x%x, result=0x%x, cr=0x%x\n",
3241 n, s, r, m, result, CR));
3242 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3244 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
3245 # long n = MASKED(*rB, 58, 63);
3246 # unsigned_word r = ROTL64(*rS, n);
3247 # long b = (mb_5 << 4) | mb_0_4;
3248 # unsigned_word m = MASK(b, 63);
3249 # signed_word result = r & m;
3251 # CR0_COMPARE(result, 0, Rc);
3253 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
3254 # long n = MASKED(*rB, 58, 63);
3255 # unsigned_word r = ROTL64(*rS, n);
3256 # long e = (me_5 << 4) | me_0_4;
3257 # unsigned_word m = MASK(0, e);
3258 # signed_word result = r & m;
3260 # CR0_COMPARE(result, 0, Rc);
3262 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
3263 # long n = MASKED(*rB, 59, 63);
3264 # unsigned32 r = ROTL32(*rS, n);
3265 # unsigned32 m = MASK(MB+32, ME+32);
3266 # signed_word result = r & m;
3268 # CR0_COMPARE(result, 0, Rc);
3270 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
3271 # long n = (sh_5 << 4) | sh_0_4;
3272 # unsigned_word r = ROTL64(*rS, n);
3273 # long b = (mb_5 << 4) | mb_0_4;
3274 # unsigned_word m = MASK(b, (64-n));
3275 # signed_word result = (r & m) | (*rA & ~m)
3277 # CR0_COMPARE(result, 0, Rc);
3279 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
3280 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3281 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3282 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3283 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3285 unsigned32 r = ROTL32(*rS, n);
3286 unsigned32 m = MASK(MB+32, ME+32);
3287 signed_word result = (r & m) | (*rA & ~m);
3289 ITRACE(trace_alu, (": n=%d *rS=0x%x r=0x%x m=0x%x result=0x%x\n",
3290 n, *rS, r, m, result));
3291 CR0_COMPARE(result, 0, Rc);
3292 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3295 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
3297 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
3298 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3299 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3300 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3301 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3302 int n = MASKED(*rB, 59, 63);
3303 unsigned32 source = *rS;
3304 signed_word shifted;
3306 shifted = (source << n);
3310 CR0_COMPARE(shifted, 0, Rc);
3312 ("n=%d, source=0x%x, shifted=0x%x\n",
3313 n, source, shifted));
3314 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3316 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3318 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
3319 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3320 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3321 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3322 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3323 int n = MASKED(*rB, 59, 63);
3324 unsigned32 source = *rS;
3325 signed_word shifted;
3327 shifted = (source >> n);
3331 CR0_COMPARE(shifted, 0, Rc);
3333 ("n=%d, source=0x%x, shifted=0x%x\n",
3334 n, source, shifted));
3335 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3337 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3339 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3340 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3341 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3342 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3343 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3345 signed_word r = ROTL32(*rS, /*64*/32-n);
3346 signed_word m = MASK(n+32, 63);
3347 int S = MASKED(*rS, 32, 32);
3348 signed_word shifted = (r & m) | (S ? ~m : 0);
3350 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3354 CR0_COMPARE(shifted, 0, Rc);
3355 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3357 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3359 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3360 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3361 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3362 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3363 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3364 int n = MASKED(*rB, 58, 63);
3365 int shift = (n >= 31 ? 31 : n);
3366 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3367 signed32 shifted = source >> shift;
3368 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
3369 *rA = (signed_word)shifted; /* if 64bit will sign extend */
3370 if (source < 0 && (source & mask))
3374 CR0_COMPARE(shifted, 0, Rc);
3375 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3378 # I.3.3.14 Move to/from System Register Instructions
3381 0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3382 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3383 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3384 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3385 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3386 int n = (spr{5:9} << 5) | spr{0:4};
3387 if (spr{0} && IS_PROBLEM_STATE(processor))
3388 program_interrupt(processor, cia,
3389 privileged_instruction_program_interrupt);
3390 else if (!spr_is_valid(n)
3391 || spr_is_readonly(n))
3392 program_interrupt(processor, cia,
3393 illegal_instruction_program_interrupt);
3395 spreg new_val = (spr_length(n) == 64
3397 : MASKED(*rS, 32, 63));
3398 /* HACK - time base registers need to be updated immediatly */
3399 if (WITH_TIME_BASE) {
3403 cpu_set_time_base(processor,
3404 (MASKED64(cpu_get_time_base(processor), 32, 63)
3405 | INSERTED64(new_val, 0, 31)));
3408 cpu_set_time_base(processor,
3409 (MASKED64(cpu_get_time_base(processor), 0, 31)
3410 | INSERTED64(new_val, 32, 63)));
3413 cpu_set_decrementer(processor, new_val);
3424 ppc_insn_to_spr(my_index, processor, cpu_model(processor), n, rS);
3426 0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3427 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3428 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3429 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3430 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3431 int n = (spr{5:9} << 5) | spr{0:4};
3432 if (spr{0} && IS_PROBLEM_STATE(processor))
3433 program_interrupt(processor, cia,
3434 privileged_instruction_program_interrupt);
3435 else if (!spr_is_valid(n))
3436 program_interrupt(processor, cia,
3437 illegal_instruction_program_interrupt);
3439 /* HACK - some SPR's need to get their value extracted specially */
3442 ppc_insn_from_spr(my_index, processor, cpu_model(processor), rT, n);
3444 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3445 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3446 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3447 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3448 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3453 unsigned_word mask = 0;
3455 for (f = 0; f < 8; f++) {
3456 if (FXM & (0x80 >> f))
3457 mask |= (0xf << 4*(7-f));
3459 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3461 ppc_insn_mtcr(my_index, processor, cpu_model(processor), rS, FXM);
3463 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3465 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3466 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3467 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3468 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3469 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3470 *rT = (unsigned32)CR;
3471 ppc_insn_mfcr(my_index, processor, cpu_model(processor), rT);
3474 # I.4.6.2 Floating-Point Load Instructions
3477 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3478 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3479 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3480 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3481 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3487 *frT = DOUBLE(MEM(unsigned, EA, 4));
3488 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 0/*RA_is_update*/);
3490 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
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 = DOUBLE(MEM(unsigned, EA, 4));
3501 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 0/*RA_is_update*/);
3503 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
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
3510 program_interrupt(processor, cia,
3511 illegal_instruction_program_interrupt);
3513 *frT = DOUBLE(MEM(unsigned, EA, 4));
3515 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 1/*RA_is_update*/);
3517 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3518 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3519 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3520 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3521 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3524 program_interrupt(processor, cia,
3525 illegal_instruction_program_interrupt);
3527 *frT = DOUBLE(MEM(unsigned, EA, 4));
3529 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 1/*RA_is_update*/);
3531 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3532 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3533 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3534 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3535 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3541 *frT = MEM(unsigned, EA, 8);
3542 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 0/*RA_is_update*/);
3544 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3545 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3546 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3547 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3548 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3554 *frT = MEM(unsigned, EA, 8);
3555 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 0/*RA_is_update*/);
3557 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3558 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3559 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3560 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3561 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3564 program_interrupt(processor, cia,
3565 illegal_instruction_program_interrupt);
3567 *frT = MEM(unsigned, EA, 8);
3569 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 1/*RA_is_update*/);
3571 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3572 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3573 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3574 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3575 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3578 program_interrupt(processor, cia,
3579 illegal_instruction_program_interrupt);
3581 *frT = MEM(unsigned, EA, 8);
3583 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 1/*RA_is_update*/);
3587 # I.4.6.3 Floating-Point Store Instructions
3590 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3591 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3592 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3593 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3594 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3600 STORE(EA, 4, SINGLE(*frS));
3601 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 0/*RA_is_update*/);
3603 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
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
3613 STORE(EA, 4, SINGLE(*frS));
3614 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 0/*RA_is_update*/);
3616 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
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
3623 program_interrupt(processor, cia,
3624 illegal_instruction_program_interrupt);
3626 STORE(EA, 4, SINGLE(*frS));
3628 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 1/*RA_is_update*/);
3630 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3631 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3632 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3633 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3634 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3637 program_interrupt(processor, cia,
3638 illegal_instruction_program_interrupt);
3640 STORE(EA, 4, SINGLE(*frS));
3642 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 1/*RA_is_update*/);
3644 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3645 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3646 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3647 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3648 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3655 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 0/*RA_is_update*/);
3657 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3658 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3659 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3660 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3661 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3668 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 0/*RA_is_update*/);
3670 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3671 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3672 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3673 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3674 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3677 program_interrupt(processor, cia,
3678 illegal_instruction_program_interrupt);
3682 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 1/*RA_is_update*/);
3684 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3685 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3686 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3687 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3688 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3691 program_interrupt(processor, cia,
3692 illegal_instruction_program_interrupt);
3696 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 1/*RA_is_update*/);
3700 # I.4.6.4 Floating-Point Move Instructions
3703 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
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
3710 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3712 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3713 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3714 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3715 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3716 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3717 *frT = *frB ^ BIT64(0);
3719 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3721 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3722 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3723 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3724 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3725 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3726 *frT = *frB & ~BIT64(0);
3728 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3730 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3731 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3732 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3733 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3734 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3735 *frT = *frB | BIT64(0);
3737 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3742 # I.4.6.5 Floating-Point Arithmetic Instructions
3745 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3746 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3747 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3748 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3749 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3751 if (is_invalid_operation(processor, cia,
3753 fpscr_vxsnan | fpscr_vxisi,
3756 invalid_arithemetic_operation(processor, cia,
3758 0, /*instruction_is_frsp*/
3759 0, /*instruction_is_convert_to_64bit*/
3760 0, /*instruction_is_convert_to_32bit*/
3761 0); /*single-precision*/
3765 double s = *(double*)frA + *(double*)frB;
3769 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3771 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3772 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3773 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3774 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3775 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3777 if (is_invalid_operation(processor, cia,
3779 fpscr_vxsnan | fpscr_vxisi,
3782 invalid_arithemetic_operation(processor, cia,
3784 0, /*instruction_is_frsp*/
3785 0, /*instruction_is_convert_to_64bit*/
3786 0, /*instruction_is_convert_to_32bit*/
3787 1); /*single-precision*/
3791 float s = *(double*)frA + *(double*)frB;
3795 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3797 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3798 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3799 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3800 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3801 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3803 if (is_invalid_operation(processor, cia,
3805 fpscr_vxsnan | fpscr_vxisi,
3808 invalid_arithemetic_operation(processor, cia,
3810 0, /*instruction_is_frsp*/
3811 0, /*instruction_is_convert_to_64bit*/
3812 0, /*instruction_is_convert_to_32bit*/
3813 0); /*single-precision*/
3817 double s = *(double*)frA - *(double*)frB;
3821 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3823 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3824 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3825 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3826 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3827 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3829 if (is_invalid_operation(processor, cia,
3831 fpscr_vxsnan | fpscr_vxisi,
3834 invalid_arithemetic_operation(processor, cia,
3836 0, /*instruction_is_frsp*/
3837 0, /*instruction_is_convert_to_64bit*/
3838 0, /*instruction_is_convert_to_32bit*/
3839 1); /*single-precision*/
3843 float s = *(double*)frA - *(double*)frB;
3846 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3849 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3850 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3851 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3852 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3853 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3855 if (is_invalid_operation(processor, cia,
3857 fpscr_vxsnan | fpscr_vximz,
3860 invalid_arithemetic_operation(processor, cia,
3862 0, /*instruction_is_frsp*/
3863 0, /*instruction_is_convert_to_64bit*/
3864 0, /*instruction_is_convert_to_32bit*/
3865 0); /*single-precision*/
3869 double s = *(double*)frA * *(double*)frC;
3873 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frC, Rc);
3875 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3876 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3877 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3878 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3879 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3881 if (is_invalid_operation(processor, cia,
3883 fpscr_vxsnan | fpscr_vximz,
3886 invalid_arithemetic_operation(processor, cia,
3888 0, /*instruction_is_frsp*/
3889 0, /*instruction_is_convert_to_64bit*/
3890 0, /*instruction_is_convert_to_32bit*/
3891 1); /*single-precision*/
3895 float s = *(double*)frA * *(double*)frC;
3899 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frC, Rc);
3901 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3902 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3903 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3904 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3905 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3907 if (is_invalid_operation(processor, cia,
3909 fpscr_vxsnan | fpscr_vxzdz,
3912 invalid_arithemetic_operation(processor, cia,
3914 0, /*instruction_is_frsp*/
3915 0, /*instruction_is_convert_to_64bit*/
3916 0, /*instruction_is_convert_to_32bit*/
3917 0); /*single-precision*/
3921 double s = *(double*)frA / *(double*)frB;
3925 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3927 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3928 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3929 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3930 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3931 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3933 if (is_invalid_operation(processor, cia,
3935 fpscr_vxsnan | fpscr_vxzdz,
3938 invalid_arithemetic_operation(processor, cia,
3940 0, /*instruction_is_frsp*/
3941 0, /*instruction_is_convert_to_64bit*/
3942 0, /*instruction_is_convert_to_32bit*/
3943 1); /*single-precision*/
3947 float s = *(double*)frA / *(double*)frB;
3951 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3953 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3954 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3955 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3956 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3957 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3959 double product; /*HACK! - incorrectly loosing precision ... */
3960 /* compute the multiply */
3961 if (is_invalid_operation(processor, cia,
3963 fpscr_vxsnan | fpscr_vximz,
3966 invalid_arithemetic_operation(processor, cia,
3967 (unsigned64*)&product, *frA, 0, *frC,
3968 0, /*instruction_is_frsp*/
3969 0, /*instruction_is_convert_to_64bit*/
3970 0, /*instruction_is_convert_to_32bit*/
3971 0); /*single-precision*/
3975 product = *(double*)frA * *(double*)frC;
3977 /* compute the add */
3978 if (is_invalid_operation(processor, cia,
3980 fpscr_vxsnan | fpscr_vxisi,
3983 invalid_arithemetic_operation(processor, cia,
3984 frT, product, *frB, 0,
3985 0, /*instruction_is_frsp*/
3986 0, /*instruction_is_convert_to_64bit*/
3987 0, /*instruction_is_convert_to_32bit*/
3988 0); /*single-precision*/
3992 double s = product + *(double*)frB;
3996 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
3998 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3999 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4000 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4001 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4002 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4004 float product; /*HACK! - incorrectly loosing precision ... */
4005 /* compute the multiply */
4006 if (is_invalid_operation(processor, cia,
4008 fpscr_vxsnan | fpscr_vximz,
4011 invalid_arithemetic_operation(processor, cia,
4012 (unsigned64*)&product, *frA, 0, *frC,
4013 0, /*instruction_is_frsp*/
4014 0, /*instruction_is_convert_to_64bit*/
4015 0, /*instruction_is_convert_to_32bit*/
4016 0); /*single-precision*/
4020 product = *(double*)frA * *(double*)frC;
4022 /* compute the add */
4023 if (is_invalid_operation(processor, cia,
4025 fpscr_vxsnan | fpscr_vxisi,
4028 invalid_arithemetic_operation(processor, cia,
4029 frT, product, *frB, 0,
4030 0, /*instruction_is_frsp*/
4031 0, /*instruction_is_convert_to_64bit*/
4032 0, /*instruction_is_convert_to_32bit*/
4033 0); /*single-precision*/
4037 float s = product + *(double*)frB;
4038 *(double*)frT = (double)s;
4041 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4043 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
4044 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4045 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4046 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4047 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4049 double product; /*HACK! - incorrectly loosing precision ... */
4050 /* compute the multiply */
4051 if (is_invalid_operation(processor, cia,
4053 fpscr_vxsnan | fpscr_vximz,
4056 invalid_arithemetic_operation(processor, cia,
4057 (unsigned64*)&product, *frA, 0, *frC,
4058 0, /*instruction_is_frsp*/
4059 0, /*instruction_is_convert_to_64bit*/
4060 0, /*instruction_is_convert_to_32bit*/
4061 0); /*single-precision*/
4065 product = *(double*)frA * *(double*)frC;
4067 /* compute the subtract */
4068 if (is_invalid_operation(processor, cia,
4070 fpscr_vxsnan | fpscr_vxisi,
4073 invalid_arithemetic_operation(processor, cia,
4074 frT, product, *frB, 0,
4075 0, /*instruction_is_frsp*/
4076 0, /*instruction_is_convert_to_64bit*/
4077 0, /*instruction_is_convert_to_32bit*/
4078 0); /*single-precision*/
4082 double s = product - *(double*)frB;
4086 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4088 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
4089 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4090 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4091 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4092 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4094 float product; /*HACK! - incorrectly loosing precision ... */
4095 /* compute the multiply */
4096 if (is_invalid_operation(processor, cia,
4098 fpscr_vxsnan | fpscr_vximz,
4101 invalid_arithemetic_operation(processor, cia,
4102 (unsigned64*)&product, *frA, 0, *frC,
4103 0, /*instruction_is_frsp*/
4104 0, /*instruction_is_convert_to_64bit*/
4105 0, /*instruction_is_convert_to_32bit*/
4106 0); /*single-precision*/
4110 product = *(double*)frA * *(double*)frC;
4112 /* compute the subtract */
4113 if (is_invalid_operation(processor, cia,
4115 fpscr_vxsnan | fpscr_vxisi,
4118 invalid_arithemetic_operation(processor, cia,
4119 frT, product, *frB, 0,
4120 0, /*instruction_is_frsp*/
4121 0, /*instruction_is_convert_to_64bit*/
4122 0, /*instruction_is_convert_to_32bit*/
4123 0); /*single-precision*/
4127 float s = product - *(double*)frB;
4128 *(double*)frT = (double)s;
4131 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4133 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
4134 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4135 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4136 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4137 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4139 double product; /*HACK! - incorrectly loosing precision ... */
4140 /* compute the multiply */
4141 if (is_invalid_operation(processor, cia,
4143 fpscr_vxsnan | fpscr_vximz,
4146 invalid_arithemetic_operation(processor, cia,
4147 (unsigned64*)&product, *frA, 0, *frC,
4148 0, /*instruction_is_frsp*/
4149 0, /*instruction_is_convert_to_64bit*/
4150 0, /*instruction_is_convert_to_32bit*/
4151 0); /*single-precision*/
4155 product = *(double*)frA * *(double*)frC;
4157 /* compute the add */
4158 if (is_invalid_operation(processor, cia,
4160 fpscr_vxsnan | fpscr_vxisi,
4163 invalid_arithemetic_operation(processor, cia,
4164 frT, product, *frB, 0,
4165 0, /*instruction_is_frsp*/
4166 0, /*instruction_is_convert_to_64bit*/
4167 0, /*instruction_is_convert_to_32bit*/
4168 0); /*single-precision*/
4172 double s = -(product + *(double*)frB);
4176 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4178 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
4179 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4180 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4181 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4182 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4184 float product; /*HACK! - incorrectly loosing precision ... */
4185 /* compute the multiply */
4186 if (is_invalid_operation(processor, cia,
4188 fpscr_vxsnan | fpscr_vximz,
4191 invalid_arithemetic_operation(processor, cia,
4192 (unsigned64*)&product, *frA, 0, *frC,
4193 0, /*instruction_is_frsp*/
4194 0, /*instruction_is_convert_to_64bit*/
4195 0, /*instruction_is_convert_to_32bit*/
4196 0); /*single-precision*/
4200 product = *(double*)frA * *(double*)frC;
4202 /* compute the add */
4203 if (is_invalid_operation(processor, cia,
4205 fpscr_vxsnan | fpscr_vxisi,
4208 invalid_arithemetic_operation(processor, cia,
4209 frT, product, *frB, 0,
4210 0, /*instruction_is_frsp*/
4211 0, /*instruction_is_convert_to_64bit*/
4212 0, /*instruction_is_convert_to_32bit*/
4213 0); /*single-precision*/
4217 float s = -(product + *(double*)frB);
4218 *(double*)frT = (double)s;
4221 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4223 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
4224 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4225 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4226 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4227 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4229 double product; /*HACK! - incorrectly loosing precision ... */
4230 /* compute the multiply */
4231 if (is_invalid_operation(processor, cia,
4233 fpscr_vxsnan | fpscr_vximz,
4236 invalid_arithemetic_operation(processor, cia,
4237 (unsigned64*)&product, *frA, 0, *frC,
4238 0, /*instruction_is_frsp*/
4239 0, /*instruction_is_convert_to_64bit*/
4240 0, /*instruction_is_convert_to_32bit*/
4241 0); /*single-precision*/
4245 product = *(double*)frA * *(double*)frC;
4247 /* compute the subtract */
4248 if (is_invalid_operation(processor, cia,
4250 fpscr_vxsnan | fpscr_vxisi,
4253 invalid_arithemetic_operation(processor, cia,
4254 frT, product, *frB, 0,
4255 0, /*instruction_is_frsp*/
4256 0, /*instruction_is_convert_to_64bit*/
4257 0, /*instruction_is_convert_to_32bit*/
4258 0); /*single-precision*/
4262 double s = -(product - *(double*)frB);
4266 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4268 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
4269 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4270 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4271 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4272 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4274 float product; /*HACK! - incorrectly loosing precision ... */
4275 /* compute the multiply */
4276 if (is_invalid_operation(processor, cia,
4278 fpscr_vxsnan | fpscr_vximz,
4281 invalid_arithemetic_operation(processor, cia,
4282 (unsigned64*)&product, *frA, 0, *frC,
4283 0, /*instruction_is_frsp*/
4284 0, /*instruction_is_convert_to_64bit*/
4285 0, /*instruction_is_convert_to_32bit*/
4286 0); /*single-precision*/
4290 product = *(double*)frA * *(double*)frC;
4292 /* compute the subtract */
4293 if (is_invalid_operation(processor, cia,
4295 fpscr_vxsnan | fpscr_vxisi,
4298 invalid_arithemetic_operation(processor, cia,
4299 frT, product, *frB, 0,
4300 0, /*instruction_is_frsp*/
4301 0, /*instruction_is_convert_to_64bit*/
4302 0, /*instruction_is_convert_to_32bit*/
4303 0); /*single-precision*/
4307 float s = -(product - *(double*)frB);
4308 *(double*)frT = (double)s;
4311 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4315 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4318 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4319 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4320 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4321 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4322 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4325 unsigned64 frac_grx;
4326 /* split off cases for what to do */
4327 if (EXTRACTED64(*frB, 1, 11) < 897
4328 && EXTRACTED64(*frB, 1, 63) > 0) {
4329 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
4330 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
4332 if (EXTRACTED64(*frB, 1, 11) > 1150
4333 && EXTRACTED64(*frB, 1, 11) < 2047) {
4334 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4335 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
4337 if (EXTRACTED64(*frB, 1, 11) > 896
4338 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
4339 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
4340 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4341 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
4342 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
4343 if (EXTRACTED64(*frB, 12, 12) == 0
4344 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
4347 Disabled_Exponent_Underflow:
4348 sign = EXTRACTED64(*frB, 0, 0);
4349 if (EXTRACTED64(*frB, 1, 11) == 0) {
4351 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4353 if (EXTRACTED64(*frB, 1, 11) > 0) {
4354 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4355 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4357 Denormalize_Operand:
4358 /* G|R|X == zero from above */
4359 while (exp < -126) {
4361 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4362 | MASKED64(frac_grx, 55, 55));
4364 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4365 Round_Single(processor, sign, &exp, &frac_grx);
4366 FPSCR_SET_XX(FPSCR & fpscr_fi);
4367 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4368 *frT = INSERTED64(sign, 0, 0);
4369 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4370 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4372 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4373 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4374 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4375 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4377 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4378 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4379 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4381 /*Normalize_Operand:*/
4382 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4384 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4386 *frT = (INSERTED64(sign, 0, 0)
4387 | INSERTED64(exp + 1023, 1, 11)
4388 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4391 Enabled_Exponent_Underflow:
4393 sign = EXTRACTED64(*frB, 0, 0);
4394 if (EXTRACTED64(*frB, 1, 11) == 0) {
4396 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4398 if (EXTRACTED64(*frB, 1, 11) > 0) {
4399 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4400 frac_grx = (BIT64(0) |
4401 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4403 /*Normalize_Operand:*/
4404 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4406 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4408 Round_Single(processor, sign, &exp, &frac_grx);
4409 FPSCR_SET_XX(FPSCR & fpscr_fi);
4411 *frT = (INSERTED64(sign, 0, 0)
4412 | INSERTED64(exp + 1023, 1, 11)
4413 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4414 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4415 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4417 Disabled_Exponent_Overflow:
4419 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4420 if (EXTRACTED64(*frB, 0, 0) == 0) {
4421 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4422 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4424 if (EXTRACTED64(*frB, 0, 0) == 1) {
4425 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4426 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4429 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4430 if (EXTRACTED64(*frB, 0, 0) == 0) {
4431 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4432 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4434 if (EXTRACTED64(*frB, 0, 0) == 1) {
4435 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4436 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4439 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4440 if (EXTRACTED64(*frB, 0, 0) == 0) {
4441 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4442 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4444 if (EXTRACTED64(*frB, 0, 0) == 1) {
4445 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4446 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4449 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4450 if (EXTRACTED64(*frB, 0, 0) == 0) {
4451 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4452 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4454 if (EXTRACTED64(*frB, 0, 0) == 1) {
4455 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4456 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4459 /* FPSCR[FR] <- undefined */
4463 Enabled_Exponent_Overflow:
4464 sign = EXTRACTED64(*frB, 0, 0);
4465 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4466 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4467 Round_Single(processor, sign, &exp, &frac_grx);
4468 FPSCR_SET_XX(FPSCR & fpscr_fi);
4472 *frT = (INSERTED64(sign, 0, 0)
4473 | INSERTED64(exp + 1023, 1, 11)
4474 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4475 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4476 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4480 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4481 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4487 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4488 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4493 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4494 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4499 FPSCR_OR_VX(fpscr_vxsnan);
4500 if ((FPSCR & fpscr_ve) == 0) {
4501 *frT = (MASKED64(*frB, 0, 11)
4503 | MASKED64(*frB, 13, 34));
4504 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4510 sign = EXTRACTED64(*frB, 0, 0);
4511 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4512 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4513 Round_Single(processor, sign, &exp, &frac_grx);
4514 FPSCR_SET_XX(FPSCR & fpscr_fi);
4515 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4516 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4517 *frT = (INSERTED64(sign, 0, 0)
4518 | INSERTED64(exp + 1023, 1, 11)
4519 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4520 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4521 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4524 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
4526 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4528 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4530 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4532 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4533 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4534 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4535 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4536 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4538 convert_to_integer(processor, cia,
4540 fpscr_rn_round_towards_zero, 32);
4542 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
4544 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4545 int sign = EXTRACTED64(*frB, 0, 0);
4547 unsigned64 frac = *frB;
4548 if (frac == 0) goto Zero_Operand;
4549 if (sign == 1) frac = ~frac + 1;
4550 while (EXTRACTED64(frac, 0, 0) == 0) {
4551 /*??? do the loop 0 times if (FRB) = max negative integer */
4552 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4555 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4556 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4557 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4558 *frT = (INSERTED64(sign, 0, 0)
4559 | INSERTED64(exp + 1023, 1, 11)
4560 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4566 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4571 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
4574 # I.4.6.7 Floating-Point Compare Instructions
4577 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4578 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4579 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4580 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4581 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4584 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4585 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4586 else if (is_less_than(frA, frB))
4587 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4588 else if (is_greater_than(frA, frB))
4589 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4591 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4593 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4594 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4595 FPSCR_OR_VX(fpscr_vxsnan);
4597 ppc_insn_fp2_cr(my_index, processor, cpu_model(processor), BF, frA, frB);
4599 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4600 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4601 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4602 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4603 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4606 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4607 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4608 else if (is_less_than(frA, frB))
4609 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4610 else if (is_greater_than(frA, frB))
4611 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4613 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4615 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4616 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4617 FPSCR_OR_VX(fpscr_vxsnan);
4618 if ((FPSCR & fpscr_ve) == 0)
4619 FPSCR_OR_VX(fpscr_vxvc);
4621 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4622 FPSCR_OR_VX(fpscr_vxvc);
4625 ppc_insn_fp2_cr(my_index, processor, cpu_model(processor), BF, frA, frB);
4629 # I.4.6.8 Floating-Point Status and Control Register Instructions
4632 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4634 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4636 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4638 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4640 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4642 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4646 # I.A.1.1 Floating-Point Store Instruction
4648 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4651 # I.A.1.2 Floating-Point Arithmetic Instructions
4654 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
4656 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4658 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
4660 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4663 # I.A.1.3 Floating-Point Select Instruction
4666 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4670 # II.3.2 Cache Management Instructions
4673 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4674 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4675 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4676 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4677 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4678 /* blindly flush all instruction cache entries */
4679 #if WITH_IDECODE_CACHE_SIZE
4680 cpu_flush_icache(processor);
4683 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4685 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4687 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4688 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4689 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4690 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4691 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4692 cpu_synchronize_context(processor);
4693 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
4697 # II.3.2.2 Data Cache Instructions
4700 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4701 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4702 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4703 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4704 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4705 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4707 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4709 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4711 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4712 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4713 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4714 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4715 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4716 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4718 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4720 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4722 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4723 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4724 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4725 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4726 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4727 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4729 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4731 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4733 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4734 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4735 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4736 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4737 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4738 TRACE(trace_tbd,("Data Cache Block Store\n"));
4740 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4742 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4744 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4745 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4746 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4747 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4748 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4749 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4751 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4753 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4756 # II.3.3 Enforce In-order Execution of I/O Instruction
4759 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4760 /* Since this model has no instruction overlap
4761 this instruction need do nothing */
4764 # II.4.1 Time Base Instructions
4767 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4768 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4769 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4770 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4771 int n = (tbr{5:9} << 5) | tbr{0:4};
4773 if (is_64bit_implementation) *rT = TB;
4774 else *rT = EXTRACTED64(TB, 32, 63);
4776 else if (n == 269) {
4777 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4778 else *rT = EXTRACTED64(TB, 0, 31);
4781 program_interrupt(processor, cia,
4782 illegal_instruction_program_interrupt);
4786 # III.2.3.1 System Linkage Instructions
4789 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4790 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4791 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4792 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4793 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4794 if (IS_PROBLEM_STATE(processor)) {
4795 program_interrupt(processor, cia,
4796 privileged_instruction_program_interrupt);
4799 MSR = (MASKED(SRR1, 0, 32)
4800 | MASKED(SRR1, 37, 41)
4801 | MASKED(SRR1, 48, 63));
4802 NIA = MASKED(SRR0, 0, 61);
4803 cpu_synchronize_context(processor);
4807 # III.3.4.1 Move to/from System Register Instructions
4810 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
4811 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
4812 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4813 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4814 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4815 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4816 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4817 if (IS_PROBLEM_STATE(processor))
4818 program_interrupt(processor, cia,
4819 privileged_instruction_program_interrupt);
4823 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4824 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4825 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4826 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4827 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4828 if (IS_PROBLEM_STATE(processor))
4829 program_interrupt(processor, cia,
4830 privileged_instruction_program_interrupt);
4836 # III.4.11.1 Cache Management Instructions
4839 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4840 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4841 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4842 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4843 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4844 if (IS_PROBLEM_STATE(processor))
4845 program_interrupt(processor, cia,
4846 privileged_instruction_program_interrupt);
4848 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4851 # III.4.11.2 Segment Register Manipulation Instructions
4854 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4855 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4856 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4857 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4858 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4859 if (IS_PROBLEM_STATE(processor))
4860 program_interrupt(processor, cia,
4861 privileged_instruction_program_interrupt);
4865 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4866 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4867 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4868 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4869 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4870 if (IS_PROBLEM_STATE(processor))
4871 program_interrupt(processor, cia,
4872 privileged_instruction_program_interrupt);
4874 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4876 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4877 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4878 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4879 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4880 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4881 if (IS_PROBLEM_STATE(processor))
4882 program_interrupt(processor, cia,
4883 privileged_instruction_program_interrupt);
4887 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4888 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4889 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4890 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4891 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4892 if (IS_PROBLEM_STATE(processor))
4893 program_interrupt(processor, cia,
4894 privileged_instruction_program_interrupt);
4896 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4900 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4903 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4905 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4907 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4909 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4911 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4915 # III.A.1.2 External Access Instructions
4918 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4920 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed