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_branch_conditional[32]; /* # of each type of bc */
131 count_type nr_stalls_data; /* # of stalls for data */
132 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
133 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
134 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
135 unsigned32 int_busy; /* int registers that are busy */
136 unsigned32 fp_busy; /* floating point registers that are busy */
137 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
138 unsigned8 spr_busy[nr_of_sprs]; /* SPR registers that are busy */
139 unsigned8 busy[nr_ppc_function_units]; /* whether a function is busy or not */
142 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
143 "unknown functional unit instruction",
144 "integer functional unit instruction",
145 "system register functional unit instruction",
146 "1st single cycle integer functional unit instruction",
147 "2nd single cycle integer functional unit instruction",
148 "multiple cycle integer functional unit instruction",
149 "floating point functional unit instruction",
150 "load/store functional unit instruction",
151 "branch functional unit instruction",
154 STATIC_MODEL const char *const ppc_branch_conditional_name[32] = {
155 "branch if --CTR != 0 and condition is FALSE", /* 0000y */
156 "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
157 "branch if --CTR == 0 and condition is FALSE", /* 0001y */
158 "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
159 "branch if the condition is FALSE", /* 001zy */
160 "branch if the condition is FALSE, reverse branch likely",
161 "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */
162 "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
163 "branch if --CTR != 0 and condition is TRUE", /* 0100y */
164 "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
165 "branch if --CTR == 0 and condition is TRUE", /* 0101y */
166 "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
167 "branch if the condition is TRUE", /* 011zy */
168 "branch if the condition is TRUE, reverse branch likely",
169 "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */
170 "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
171 "branch if --CTR != 0", /* 1z00y */
172 "branch if --CTR != 0, reverse branch likely",
173 "branch if --CTR == 0", /* 1z01y */
174 "branch if --CTR == 0, reverse branch likely",
175 "branch always", /* 1z1zz */
176 "branch always (ignored bit 5 set to 1)",
177 "branch always (ignored bit 4 set to 1)", /* 1z1zz */
178 "branch always (ignored bits 4,5 set to 1)",
179 "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */
180 "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
181 "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */
182 "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
183 "branch always (ignored bit 1 set to 1)", /* 1z1zz */
184 "branch always (ignored bits 1,5 set to 1)",
185 "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */
186 "branch always (ignored bits 1,4,5 set to 1)",
190 # Trace releasing resources
191 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
193 TRACE(trace_model,("done, %s\n", ppc_function_unit_name[busy->unit]));
194 if (busy->int_busy) {
195 for(i = 0; i < 32; i++) {
196 if (((1 << i) & busy->int_busy) != 0) {
197 TRACE(trace_model, ("Register r%d is now available.\n", i));
202 for(i = 0; i < 32; i++) {
203 if (((1 << i) & busy->fp_busy) != 0) {
204 TRACE(trace_model, ("Register f%d is now available.\n", i));
208 if (busy->cr_fpscr_busy) {
209 for(i = 0; i < 8; i++) {
210 if (((1 << i) & busy->cr_fpscr_busy) != 0) {
211 TRACE(trace_model, ("Register cr%d is now available.\n", i));
214 if (busy->cr_fpscr_busy & 0x100)
215 TRACE(trace_model, ("Register fpscr is now available.\n"));
217 if (busy->spr_busy != PPC_NO_SPR)
218 TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
220 # Trace waiting for registers to become available
221 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
224 int_busy &= model_ptr->int_busy;
225 for(i = 0; i < 32; i++) {
226 if (((1 << i) & int_busy) != 0) {
227 TRACE(trace_model, ("Waiting for register r%d.\n", i));
232 fp_busy &= model_ptr->fp_busy;
233 for(i = 0; i < 32; i++) {
234 if (((1 << i) & fp_busy) != 0) {
235 TRACE(trace_model, ("Waiting for register f%d.\n", i));
239 if (cr_or_fpscr_busy) {
240 cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
241 for(i = 0; i < 8; i++) {
242 if (((1 << i) & cr_or_fpscr_busy) != 0) {
243 TRACE(trace_model, ("Waiting for register cr%d.\n", i));
246 if (cr_or_fpscr_busy & 0x100)
247 TRACE(trace_model, ("Waiting for register fpscr.\n"));
249 if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
250 TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
252 # Advance state to next cycle, releasing any registers allocated
253 void::model-internal::model_new_cycle:model_data *model_ptr
254 model_busy *cur_busy = model_ptr->busy_list;
255 model_busy *free_list = model_ptr->free_list;
256 model_busy *next_busy = (model_busy *)0;
259 model_ptr->nr_cycles++;
260 for ( ; cur_busy; cur_busy = next) {
261 next = cur_busy->next;
262 if (--cur_busy->done <= 0) { /* function unit done, release registers */
263 model_ptr->int_busy &= ~cur_busy->int_busy;
264 model_ptr->fp_busy &= ~cur_busy->fp_busy;
265 model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
266 if (cur_busy->spr_busy != PPC_NO_SPR)
267 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
269 if (WITH_TRACE && ppc_trace[trace_model])
270 model_trace_release(model_ptr, cur_busy);
272 model_ptr->busy[cur_busy->unit] = 0;
273 cur_busy->next = free_list;
274 free_list = cur_busy;
276 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
277 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
278 model_ptr->busy[cur_busy->unit] = 0;
279 cur_busy->next = next_busy;
280 next_busy = cur_busy;
283 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
284 ppc_function_unit_name[cur_busy->unit],
287 cur_busy->next = next_busy;
288 next_busy = cur_busy;
292 model_ptr->busy_list = next_busy;
293 model_ptr->free_list = free_list;
295 # Mark a function unit as busy, return the busy structure
296 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
299 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
301 if (!model_ptr->free_list) {
302 busy = ZALLOC(model_busy);
305 busy = model_ptr->free_list;
306 model_ptr->free_list = busy->next;
308 busy->next = model_ptr->busy_list;
314 busy->cr_fpscr_busy = 0;
315 busy->spr_busy = PPC_NO_SPR;
316 model_ptr->busy_list = busy;
317 model_ptr->busy[unit] = 1;
318 model_ptr->nr_units[unit]++;
321 # Make a given integer register busy
322 void::model-internal::model_make_int_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
323 TRACE(trace_model,("Marking register r%d as busy\n", regno));
324 busy_ptr->int_busy |= (1 << regno);
325 model_ptr->int_busy |= (1 << regno);
327 # Make a given floating point register busy
328 void::model-internal::model_make_fp_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
329 TRACE(trace_model,("Marking register f%d as busy\n", regno));
330 busy_ptr->fp_busy |= (1 << regno);
331 model_ptr->fp_busy |= (1 << regno);
333 # Make a given CR register busy
334 void::model-internal::model_make_cr_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
335 TRACE(trace_model,("Marking register cr%d as busy\n", regno));
336 busy_ptr->cr_fpscr_busy |= (1 << regno);
337 model_ptr->cr_fpscr_busy |= (1 << regno);
339 # Make a given SPR register busy
340 void::model-internal::model_make_spr_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
341 TRACE(trace_model,("Marking register %s as busy\n", spr_name(regno)));
342 busy_ptr->spr_busy = regno;
343 model_ptr->spr_busy[regno] = 1;
346 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
347 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
348 ppc_function_unit first_unit = time_ptr->first_unit;
349 ppc_function_unit second_unit = time_ptr->second_unit;
350 int stall_increment = 0;
353 if (!model_ptr->busy[first_unit])
354 return model_make_busy(model_ptr, first_unit,
355 model_ptr->timing[index].issue,
356 model_ptr->timing[index].done);
358 if (!model_ptr->busy[second_unit])
359 return model_make_busy(model_ptr, second_unit,
360 model_ptr->timing[index].issue,
361 model_ptr->timing[index].done);
363 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
364 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
366 model_new_cycle(model_ptr);
369 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
370 void::model-function::model_serialize:itable_index index, model_data *model_ptr
371 while (model_ptr->busy_list) {
372 TRACE(trace_model,("waiting for pipeline to empty\n"));
373 model_ptr->nr_stalls_serialize++;
374 model_new_cycle(model_ptr);
376 (void) model_make_busy(model_ptr,
377 model_ptr->timing[index].first_unit,
378 model_ptr->timing[index].issue,
379 model_ptr->timing[index].done);
381 # Wait for a CR to become unbusy
382 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
386 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
389 cr_mask = (1 << cr_var);
390 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
391 TRACE(trace_model,("waiting for CR %d\n", cr_var));
392 model_ptr->nr_stalls_data++;
393 model_new_cycle(model_ptr);
396 # Schedule an instruction that takes 2 integer input registers and produces an output register & possibly sets CR0
397 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
398 registers *cpu_regs = cpu_registers(processor);
399 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
400 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
401 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
402 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RD);
403 model_busy *busy_ptr;
405 if (!WITH_MODEL_ISSUE)
409 if ((model_ptr->int_busy & int_mask) != 0) {
410 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
412 while ((model_ptr->int_busy & int_mask) != 0) {
413 if (WITH_TRACE && ppc_trace[trace_model])
414 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
416 model_ptr->nr_stalls_data++;
417 model_new_cycle(model_ptr);
421 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
422 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
427 const unsigned32 cr_mask = (1 << 0);
429 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
430 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
432 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
433 if (WITH_TRACE && ppc_trace[trace_model])
434 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
436 model_ptr->nr_stalls_data++;
437 model_new_cycle(model_ptr);
441 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
442 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
443 model_make_cr_reg_busy(model_ptr, busy_ptr, 0);
447 # Schedule an instruction that takes 1 integer input registers and produces an output register & possibly sets CR0
448 void::model-function::ppc_insn_int1:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA, unsigned Rc
449 registers *cpu_regs = cpu_registers(processor);
450 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
451 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
452 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RD);
453 model_busy *busy_ptr;
455 if (!WITH_MODEL_ISSUE)
459 if ((model_ptr->int_busy & int_mask) != 0) {
460 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
462 while ((model_ptr->int_busy & int_mask) != 0) {
463 if (WITH_TRACE && ppc_trace[trace_model])
464 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
466 model_ptr->nr_stalls_data++;
467 model_new_cycle(model_ptr);
471 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
472 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
477 const unsigned32 cr_mask = (1 << 0);
479 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
480 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
482 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
483 if (WITH_TRACE && ppc_trace[trace_model])
484 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
486 model_ptr->nr_stalls_data++;
487 model_new_cycle(model_ptr);
491 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
492 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
493 model_make_cr_reg_busy(model_ptr, busy_ptr, 0);
497 # Schedule an instruction that takes no integer input registers and produces an output register & possibly sets CR0
498 void::model-function::ppc_insn_int0:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, unsigned Rc
499 registers *cpu_regs = cpu_registers(processor);
500 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
501 const unsigned32 int_mask = (1 << ppc_RD);
502 model_busy *busy_ptr;
504 if (!WITH_MODEL_ISSUE)
508 while ((model_ptr->int_busy & int_mask) != 0) {
509 if (WITH_TRACE && ppc_trace[trace_model])
510 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
512 model_ptr->nr_stalls_data++;
513 model_new_cycle(model_ptr);
516 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
517 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
522 const unsigned32 cr_mask = (1 << 0);
524 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
525 if (WITH_TRACE && ppc_trace[trace_model])
526 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
528 model_ptr->nr_stalls_data++;
529 model_new_cycle(model_ptr);
532 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
533 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
534 model_make_cr_reg_busy(model_ptr, busy_ptr, 0);
538 # Schedule an instruction that takes 2 integer input registers and produces an output register & updates a second register
539 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
540 if (!WITH_MODEL_ISSUE)
544 registers *cpu_regs = cpu_registers(processor);
545 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
546 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
547 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
548 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RD);
549 model_busy *busy_ptr;
551 if ((model_ptr->int_busy & int_mask) != 0) {
552 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
554 while ((model_ptr->int_busy & int_mask) != 0) {
555 if (WITH_TRACE && ppc_trace[trace_model])
556 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
558 model_ptr->nr_stalls_data++;
559 model_new_cycle(model_ptr);
563 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
564 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
565 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
568 # Schedule an instruction that takes 1 integer input registers and produces an output register & updates the other register
569 void::model-function::ppc_insn_int1_update:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA
570 if (!WITH_MODEL_ISSUE)
574 registers *cpu_regs = cpu_registers(processor);
575 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
576 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
577 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RD);
578 model_busy *busy_ptr;
580 if ((model_ptr->int_busy & int_mask) != 0) {
581 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
583 while ((model_ptr->int_busy & int_mask) != 0) {
584 if (WITH_TRACE && ppc_trace[trace_model])
585 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
587 model_ptr->nr_stalls_data++;
588 model_new_cycle(model_ptr);
592 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
593 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
594 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
597 # Schedule an instruction that takes 2 integer input registers and produces no output register
598 void::model-function::ppc_insn_int2_noout:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rA, signed_word *rB
599 if (!WITH_MODEL_ISSUE)
603 registers *cpu_regs = cpu_registers(processor);
604 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
605 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
606 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB);
608 if ((model_ptr->int_busy & int_mask) != 0) {
609 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
611 while ((model_ptr->int_busy & int_mask) != 0) {
612 if (WITH_TRACE && ppc_trace[trace_model])
613 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
615 model_ptr->nr_stalls_data++;
616 model_new_cycle(model_ptr);
620 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
623 # Schedule an instruction that takes 1 integer input registers and produces no output register
624 void::model-function::ppc_insn_int1_noout:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rA
625 if (!WITH_MODEL_ISSUE)
629 registers *cpu_regs = cpu_registers(processor);
630 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
631 const unsigned32 int_mask = (1 << ppc_RA);
633 if ((model_ptr->int_busy & int_mask) != 0) {
634 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
636 while ((model_ptr->int_busy & int_mask) != 0) {
637 if (WITH_TRACE && ppc_trace[trace_model])
638 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
640 model_ptr->nr_stalls_data++;
641 model_new_cycle(model_ptr);
645 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
648 # Schedule an instruction that takes no input registers and produces no output
649 void::model-function::ppc_insn_int0_noout:itable_index index, cpu *processor, model_data *model_ptr
650 if (!WITH_MODEL_ISSUE)
654 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
657 # Schedule an instruction that takes 2 integer input registers and produces a CR output register
658 void::model-function::ppc_insn_int2_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, signed_word *rA, signed_word *rB
659 if (!WITH_MODEL_ISSUE)
663 registers *cpu_regs = cpu_registers(processor);
664 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
665 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
666 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB);
667 const unsigned32 cr_mask = (1 << CRD);
668 model_busy *busy_ptr;
670 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
671 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
673 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
674 if (WITH_TRACE && ppc_trace[trace_model])
675 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
677 model_ptr->nr_stalls_data++;
678 model_new_cycle(model_ptr);
682 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
683 model_make_cr_reg_busy(model_ptr, busy_ptr, CRD);
686 # Schedule an instruction that takes 1 integer input register and produces a CR output register
687 void::model-function::ppc_insn_int1_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, signed_word *rA
688 if (!WITH_MODEL_ISSUE)
692 registers *cpu_regs = cpu_registers(processor);
693 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
694 const unsigned32 int_mask = (1 << ppc_RA);
695 const unsigned32 cr_mask = (1 << CRD);
696 model_busy *busy_ptr;
698 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
699 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
701 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
702 if (WITH_TRACE && ppc_trace[trace_model])
703 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
705 model_ptr->nr_stalls_data++;
706 model_new_cycle(model_ptr);
710 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
711 model_make_cr_reg_busy(model_ptr, busy_ptr, CRD);
714 # Schedule an instruction that takes 3 floating point input registers and produces an output register & possibly sets CR1
715 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
716 registers *cpu_regs = cpu_registers(processor);
717 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
718 const unsigned ppc_RB = (rB - &cpu_regs->fpr[0]);
719 const unsigned ppc_RC = (rC - &cpu_regs->fpr[0]);
720 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
721 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RC) | (1 << ppc_RD);
722 model_busy *busy_ptr;
724 if (!WITH_MODEL_ISSUE)
728 if ((model_ptr->fp_busy & fp_mask) != 0) {
729 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
731 while ((model_ptr->fp_busy & fp_mask) != 0) {
732 if (WITH_TRACE && ppc_trace[trace_model])
733 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
735 model_ptr->nr_stalls_data++;
736 model_new_cycle(model_ptr);
740 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
741 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
746 const unsigned32 cr_mask = (1 << 1);
747 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
748 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
750 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
751 if (WITH_TRACE && ppc_trace[trace_model])
752 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
754 model_ptr->nr_stalls_data++;
755 model_new_cycle(model_ptr);
759 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
760 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
761 model_make_cr_reg_busy(model_ptr, busy_ptr, 1);
765 # Schedule an instruction that takes 2 floating point input registers and produces an output register & possibly sets CR1
766 void::model-function::ppc_insn_fp2:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, unsigned64 *rA, unsigned64 *rB, unsigned Rc
767 registers *cpu_regs = cpu_registers(processor);
768 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
769 const unsigned ppc_RB = (rB - &cpu_regs->fpr[0]);
770 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
771 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RD);
772 model_busy *busy_ptr;
774 if (!WITH_MODEL_ISSUE)
778 if ((model_ptr->fp_busy & fp_mask) != 0) {
779 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
781 while ((model_ptr->fp_busy & fp_mask) != 0) {
782 if (WITH_TRACE && ppc_trace[trace_model])
783 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
785 model_ptr->nr_stalls_data++;
786 model_new_cycle(model_ptr);
790 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
791 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
795 const unsigned32 cr_mask = (1 << 1);
797 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
798 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
800 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
801 if (WITH_TRACE && ppc_trace[trace_model])
802 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
804 model_ptr->nr_stalls_data++;
805 model_new_cycle(model_ptr);
809 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
810 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
811 model_make_cr_reg_busy(model_ptr, busy_ptr, 1);
814 # Schedule an instruction that takes 1 floating point input registers and produces an output register & possibly sets CR1
815 void::model-function::ppc_insn_fp1:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, unsigned64 *rA, unsigned Rc
816 registers *cpu_regs = cpu_registers(processor);
817 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
818 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
819 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RD);
820 model_busy *busy_ptr;
822 if (!WITH_MODEL_ISSUE)
826 if ((model_ptr->fp_busy & fp_mask) != 0) {
827 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
829 while ((model_ptr->fp_busy & fp_mask) != 0) {
830 if (WITH_TRACE && ppc_trace[trace_model])
831 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
833 model_ptr->nr_stalls_data++;
834 model_new_cycle(model_ptr);
838 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
839 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
843 const unsigned32 cr_mask = (1 << 1);
845 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
846 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
848 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
849 if (WITH_TRACE && ppc_trace[trace_model])
850 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
852 model_ptr->nr_stalls_data++;
853 model_new_cycle(model_ptr);
857 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
858 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
859 model_make_cr_reg_busy(model_ptr, busy_ptr, 1);
862 # Schedule an instruction that takes 1 floating point input register & 2 integer registers and does not produce an output
863 # (or takes 2 integer registers and produces an output in the floating point register)
864 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
865 if (!WITH_MODEL_ISSUE)
869 registers *cpu_regs = cpu_registers(processor);
870 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
871 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
872 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
873 const unsigned32 int_mask = (1 << ppc_RB) | ((ppc_RA == 0) ? 0 : (1 << ppc_RA));
874 const unsigned32 fp_mask = (1 << ppc_RD);
875 model_busy *busy_ptr;
877 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
878 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
880 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
881 if (WITH_TRACE && ppc_trace[trace_model])
882 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
884 model_ptr->nr_stalls_data++;
885 model_new_cycle(model_ptr);
889 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
891 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
894 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
897 # Schedule an instruction that takes 1 floating point input register & 1 integer register and does not produce an output
898 # (or takes 1 integer register and produces an output in the floating point register)
899 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
900 if (!WITH_MODEL_ISSUE)
904 registers *cpu_regs = cpu_registers(processor);
905 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
906 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
907 const unsigned32 int_mask = ((ppc_RA == 0) ? 0 : (1 << ppc_RA));
908 const unsigned32 fp_mask = (1 << ppc_RD);
909 model_busy *busy_ptr;
911 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
912 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
914 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
915 if (WITH_TRACE && ppc_trace[trace_model])
916 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
918 model_ptr->nr_stalls_data++;
919 model_new_cycle(model_ptr);
923 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
925 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
928 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
931 # Schedule an instruction that takes 2 floating input registers and produces a CR output register
932 void::model-function::ppc_insn_fp2_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, unsigned64 *rA, unsigned64 *rB
933 if (!WITH_MODEL_ISSUE)
937 registers *cpu_regs = cpu_registers(processor);
938 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
939 const unsigned ppc_RB = (rB - &cpu_regs->fpr[0]);
940 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RB);
941 const unsigned32 cr_mask = (1 << CRD);
942 model_busy *busy_ptr;
944 if (((model_ptr->fp_busy & fp_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
945 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
947 while (((model_ptr->fp_busy & fp_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
948 if (WITH_TRACE && ppc_trace[trace_model])
949 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
951 model_ptr->nr_stalls_data++;
952 model_new_cycle(model_ptr);
956 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
957 model_make_cr_reg_busy(model_ptr, busy_ptr, CRD);
960 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
961 void::model-function::ppc_insn_from_spr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, unsigned nSPR
962 if (!WITH_MODEL_ISSUE)
966 registers *cpu_regs = cpu_registers(processor);
967 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
968 const unsigned32 int_mask = (1 << ppc_RD);
969 model_busy *busy_ptr;
971 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
972 if (WITH_TRACE && ppc_trace[trace_model])
973 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
975 model_ptr->nr_stalls_data++;
976 model_new_cycle(model_ptr);
979 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
980 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
983 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
984 void::model-function::ppc_insn_to_spr:itable_index index, cpu *processor, model_data *model_ptr, unsigned nSPR, signed_word *rS
985 if (!WITH_MODEL_ISSUE)
989 registers *cpu_regs = cpu_registers(processor);
990 const unsigned ppc_RS = (rS - &cpu_regs->gpr[0]);
991 const unsigned32 int_mask = (1 << ppc_RS);
992 model_busy *busy_ptr;
994 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
995 if (WITH_TRACE && ppc_trace[trace_model])
996 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
998 model_ptr->nr_stalls_data++;
999 model_new_cycle(model_ptr);
1002 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1003 model_make_spr_reg_busy(model_ptr, busy_ptr, nSPR);
1006 # Schedule a MFCR instruction that moves the CR into an integer regsiter
1007 void::model-function::ppc_insn_mfcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD
1008 if (!WITH_MODEL_ISSUE)
1012 registers *cpu_regs = cpu_registers(processor);
1013 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
1014 const unsigned32 int_mask = (1 << ppc_RD);
1015 const unsigned32 cr_mask = 0xff;
1016 model_busy *busy_ptr;
1018 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
1019 if (WITH_TRACE && ppc_trace[trace_model])
1020 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
1022 model_ptr->nr_stalls_data++;
1023 model_new_cycle(model_ptr);
1026 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1027 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
1030 # Schedule a MTCR instruction that moves an integer register into the CR
1031 void::model-function::ppc_insn_mtcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rT, unsigned FXM
1032 if (!WITH_MODEL_ISSUE)
1036 registers *cpu_regs = cpu_registers(processor);
1037 const unsigned ppc_RT = (rT - &cpu_regs->gpr[0]);
1038 const unsigned32 int_mask = (1 << ppc_RT);
1039 const unsigned32 cr_mask = 0xff;
1040 const model_time *normal_time = &model_ptr->timing[index];
1041 static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 };
1042 model_busy *busy_ptr;
1045 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
1046 if (WITH_TRACE && ppc_trace[trace_model])
1047 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
1049 model_ptr->nr_stalls_data++;
1050 model_new_cycle(model_ptr);
1053 /* If only one bit is being moved, use the SCIU, not the MCIU on the 604 */
1054 if (CURRENT_MODEL == MODEL_ppc604 && (FXM & (FXM-1)) == 0) {
1055 normal_time = &ppc604_1bit_time;
1058 busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
1059 for (i = 0; i < 8; i++) {
1060 model_make_cr_reg_busy(model_ptr, busy_ptr, i);
1064 # Convert a BIT32(x) number back into the original number
1065 int::model-internal::ppc_undo_bit32:unsigned bitmask
1066 unsigned u = 0x80000000;
1068 while (u && (u & bitmask) == 0) {
1075 # Schedule an instruction that takes 2 CR input registers and produces an output CR register
1076 void::model-function::ppc_insn_cr2:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned crA_bit, unsigned crB_bit
1077 if (!WITH_MODEL_ISSUE)
1081 const unsigned ppc_CRA = ppc_undo_bit32(crA_bit);
1082 const unsigned ppc_CRB = ppc_undo_bit32(crB_bit);
1083 const unsigned32 cr_mask = (1 << ppc_CRA) | (1 << ppc_CRB) | (1 << crD);
1084 model_busy *busy_ptr;
1086 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
1087 if (WITH_TRACE && ppc_trace[trace_model])
1088 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
1090 model_ptr->nr_stalls_data++;
1091 model_new_cycle(model_ptr);
1094 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1095 model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
1098 # Schedule an instruction that takes 1 CR input registers and produces an output CR register
1099 void::model-function::ppc_insn_cr1:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned CRA
1100 if (!WITH_MODEL_ISSUE)
1104 const unsigned32 cr_mask = (1 << CRA) | (1 << crD);
1105 model_busy *busy_ptr;
1107 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
1108 if (WITH_TRACE && ppc_trace[trace_model])
1109 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
1111 model_ptr->nr_stalls_data++;
1112 model_new_cycle(model_ptr);
1115 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1116 model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
1119 model_data *::model-function::model_create:cpu *processor
1120 model_data *model_ptr = ZALLOC(model_data);
1121 ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
1122 model_ptr->name = model_name[CURRENT_MODEL];
1123 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
1124 model_ptr->processor = processor;
1125 model_ptr->nr_cycles = 1;
1128 void::model-function::model_init:model_data *model_ptr
1130 void::model-function::model_halt:model_data *model_ptr
1131 /* Let pipeline drain */
1132 while (model_ptr->busy_list)
1133 model_new_cycle(model_ptr);
1135 model_print *::model-function::model_mon_info:model_data *model_ptr
1138 ppc_function_unit i;
1139 count_type nr_insns;
1142 head = tail = ZALLOC(model_print);
1143 tail->count = model_ptr->nr_cycles;
1144 tail->name = "cycle";
1145 tail->suffix_plural = "s";
1146 tail->suffix_singular = "";
1148 if (model_ptr->nr_stalls_data) {
1149 tail->next = ZALLOC(model_print);
1151 tail->count = model_ptr->nr_stalls_data;
1152 tail->name = "stall";
1153 tail->suffix_plural = "s waiting for data";
1154 tail->suffix_singular = " waiting for data";
1157 if (model_ptr->nr_stalls_unit) {
1158 tail->next = ZALLOC(model_print);
1160 tail->count = model_ptr->nr_stalls_unit;
1161 tail->name = "stall";
1162 tail->suffix_plural = "s waiting for a function unit";
1163 tail->suffix_singular = " waiting for a function unit";
1166 if (model_ptr->nr_stalls_serialize) {
1167 tail->next = ZALLOC(model_print);
1169 tail->count = model_ptr->nr_stalls_serialize;
1170 tail->name = "stall";
1171 tail->suffix_plural = "s waiting for serialization";
1172 tail->suffix_singular = " waiting for serialization";
1175 if (model_ptr->nr_branches) {
1176 tail->next = ZALLOC(model_print);
1178 tail->count = model_ptr->nr_branches;
1179 tail->name = "branch";
1180 tail->suffix_plural = "es";
1181 tail->suffix_singular = "";
1184 if (model_ptr->nr_branches_fallthrough) {
1185 tail->next = ZALLOC(model_print);
1187 tail->count = model_ptr->nr_branches_fallthrough;
1188 tail->name = "conditional branch";
1189 tail->suffix_plural = "es fell through";
1190 tail->suffix_singular = " fell through";
1193 if (model_ptr->nr_branch_predict_trues) {
1194 tail->next = ZALLOC(model_print);
1196 tail->count = model_ptr->nr_branch_predict_trues;
1197 tail->name = "successful branch prediction";
1198 tail->suffix_plural = "s";
1199 tail->suffix_singular = "";
1202 if (model_ptr->nr_branch_predict_falses) {
1203 tail->next = ZALLOC(model_print);
1205 tail->count = model_ptr->nr_branch_predict_falses;
1206 tail->name = "unsuccessful branch prediction";
1207 tail->suffix_plural = "s";
1208 tail->suffix_singular = "";
1211 for (j = 0; j < (sizeof(ppc_branch_conditional_name) / sizeof(ppc_branch_conditional_name[0])) ; j++) {
1212 if (model_ptr->nr_branch_conditional[j]) {
1213 tail->next = ZALLOC(model_print);
1215 tail->count = model_ptr->nr_branch_conditional[j];
1216 tail->name = ppc_branch_conditional_name[j];
1217 tail->suffix_plural = " conditional branches";
1218 tail->suffix_singular = " conditional branch";
1223 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
1224 if (model_ptr->nr_units[i]) {
1225 nr_insns += model_ptr->nr_units[i];
1226 tail->next = ZALLOC(model_print);
1228 tail->count = model_ptr->nr_units[i];
1229 tail->name = ppc_function_unit_name[i];
1230 tail->suffix_plural = "s";
1231 tail->suffix_singular = "";
1235 tail->next = ZALLOC(model_print);
1237 tail->count = nr_insns;
1238 tail->name = "instruction";
1239 tail->suffix_plural = "s that were accounted for in timing info";
1240 tail->suffix_singular = " that was accounted for in timing info";
1242 tail->next = (model_print *)0;
1245 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
1247 model_print *next = ptr->next;
1252 void::model-function::model_branches:model_data *model_ptr, int failed, int conditional
1253 model_ptr->nr_units[PPC_UNIT_BPU]++;
1255 model_ptr->nr_branches_fallthrough++;
1257 model_ptr->nr_branches++;
1258 if (conditional >= 0)
1259 model_ptr->nr_branch_conditional[conditional]++;
1260 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
1262 void::model-function::model_branch_predict:model_data *model_ptr, int success
1264 model_ptr->nr_branch_predict_trues++;
1266 model_ptr->nr_branch_predict_falses++;
1269 # The following (illegal) instruction is `known' by gen and is
1270 # called when ever an illegal instruction is encountered
1272 program_interrupt(processor, cia,
1273 illegal_instruction_program_interrupt);
1277 # The following (floating point unavailable) instruction is `known' by gen
1278 # and is called when ever an a floating point instruction is to be
1279 # executed but floating point is make unavailable by the MSR
1280 ::internal::floating_point_unavailable
1281 floating_point_unavailable_interrupt(processor, cia);
1286 # Floating point support functions
1289 # Convert 32bit single to 64bit double
1290 unsigned64::function::DOUBLE:unsigned32 WORD
1292 if (EXTRACTED32(WORD, 1, 8) > 0
1293 && EXTRACTED32(WORD, 1, 8) < 255) {
1294 /* normalized operand */
1295 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
1296 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
1297 | INSERTED64(not_word_1_1, 2, 2)
1298 | INSERTED64(not_word_1_1, 3, 3)
1299 | INSERTED64(not_word_1_1, 4, 4)
1300 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
1302 else if (EXTRACTED32(WORD, 1, 8) == 0
1303 && EXTRACTED32(WORD, 9, 31) != 0) {
1304 /* denormalized operand */
1305 int sign = EXTRACTED32(WORD, 0, 0);
1307 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
1308 /* normalize the operand */
1309 while (MASKED64(frac, 0, 0) == 0) {
1313 FRT = (INSERTED64(sign, 0, 0)
1314 | INSERTED64(exp + 1023, 1, 11)
1315 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
1317 else if (EXTRACTED32(WORD, 1, 8) == 255
1318 || EXTRACTED32(WORD, 1, 31) == 0) {
1319 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
1320 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
1321 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
1322 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
1323 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
1326 error("DOUBLE - unknown case\n");
1331 # Convert 64bit single to 32bit double
1332 unsigned32::function::SINGLE:unsigned64 FRS
1334 if (EXTRACTED64(FRS, 1, 11) > 896
1335 || EXTRACTED64(FRS, 1, 63) == 0) {
1336 /* no denormalization required (includes Zero/Infinity/NaN) */
1337 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
1338 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
1340 else if (874 <= EXTRACTED64(FRS, 1, 11)
1341 && EXTRACTED64(FRS, 1, 11) <= 896) {
1342 /* denormalization required */
1343 int sign = EXTRACTED64(FRS, 0, 0);
1344 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
1345 unsigned64 frac = (BIT64(0)
1346 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
1347 /* denormalize the operand */
1348 while (exp < -126) {
1349 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1352 WORD = (INSERTED32(sign, 0, 0)
1353 | INSERTED32(0x00, 1, 8)
1354 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
1357 WORD = 0x0; /* ??? */
1362 # round 64bit double to 64bit but single
1363 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
1364 /* comparisons ignore u bits */
1367 int lsb = EXTRACTED64(*frac_grx, 23, 23);
1368 int gbit = EXTRACTED64(*frac_grx, 24, 24);
1369 int rbit = EXTRACTED64(*frac_grx, 25, 25);
1370 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
1371 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
1372 if (lsb == 1 && gbit == 1) inc = 1;
1373 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1374 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1376 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
1377 if (sign == 0 && gbit == 1) inc = 1;
1378 if (sign == 0 && rbit == 1) inc = 1;
1379 if (sign == 0 && xbit == 1) inc = 1;
1381 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
1382 if (sign == 1 && gbit == 1) inc = 1;
1383 if (sign == 1 && rbit == 1) inc = 1;
1384 if (sign == 1 && xbit == 1) inc = 1;
1386 /* work out addition in low 25 bits of out */
1387 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
1388 *frac_grx = INSERTED64(out, 0, 23);
1389 if (out & BIT64(64 - 23 - 1 - 1)) {
1390 *frac_grx = (BIT64(0) |
1391 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
1394 /* frac_grx[24:52] = 0 already */
1396 FPSCR_SET_FI(gbit || rbit || xbit);
1400 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
1402 if (round_mode == fpscr_rn_round_to_nearest) {
1403 if (*frac64 == 1 && gbit == 1) inc = 1;
1404 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
1405 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
1407 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1408 if (sign == 0 && gbit == 1) inc = 1;
1409 if (sign == 0 && rbit == 1) inc = 1;
1410 if (sign == 0 && xbit == 1) inc = 1;
1412 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1413 if (sign == 1 && gbit == 1) inc = 1;
1414 if (sign == 1 && rbit == 1) inc = 1;
1415 if (sign == 1 && xbit == 1) inc = 1;
1417 /* frac[0:64] = frac[0:64} + inc */
1418 *frac += (*frac64 && inc ? 1 : 0);
1419 *frac64 = (*frac64 + inc) & 0x1;
1421 FPSCR_SET_FI(gbit | rbit | xbit);
1424 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
1427 int lsb = EXTRACTED64(*frac, 52, 52);
1428 int gbit = EXTRACTED64(*frac, 53, 53);
1429 int rbit = EXTRACTED64(*frac, 54, 54);
1430 int xbit = EXTRACTED64(*frac, 55, 55);
1431 if (round_mode == fpscr_rn_round_to_nearest) {
1432 if (lsb == 1 && gbit == 1) inc = 1;
1433 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1434 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1436 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1437 if (sign == 0 && gbit == 1) inc = 1;
1438 if (sign == 0 && rbit == 1) inc = 1;
1439 if (sign == 0 && xbit == 1) inc = 1;
1441 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1442 if (sign == 1 && gbit == 1) inc = 1;
1443 if (sign == 1 && rbit == 1) inc = 1;
1444 if (sign == 1 && xbit == 1) inc = 1;
1446 /* frac//carry_out = frac + inc */
1447 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1448 carry_out = EXTRACTED64(*frac, 0, 0);
1450 if (carry_out == 1) *exp = *exp + 1;
1452 FPSCR_SET_FI(gbit | rbit | xbit);
1453 FPSCR_SET_XX(FPSCR & fpscr_fi);
1456 # conversion of FP to integer
1457 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
1460 unsigned64 frac = 0;
1465 int sign = EXTRACTED64(frb, 0, 0);
1466 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1467 goto Infinity_Operand;
1468 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1470 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1472 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
1473 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1474 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1475 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1476 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1479 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1480 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1483 gbit = 0, rbit = 0, xbit = 0;
1484 for (i = 1; i <= 63 - exp; i++) {
1488 frac64 = EXTRACTED64(frac, 63, 63);
1489 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1491 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1492 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1495 frac += (frac64 ? 1 : 0);
1496 frac64 = (frac64 + 1) & 0x1;
1498 if (tgt_precision == 32 /* can ignore frac64 in compare */
1499 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1501 if (tgt_precision == 64 /* can ignore frac64 in compare */
1502 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1504 if (tgt_precision == 32 /* can ignore frac64 in compare */
1505 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1507 if (tgt_precision == 64 /* can ignore frac64 in compare */
1508 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1510 FPSCR_SET_XX(FPSCR & fpscr_fi);
1511 if (tgt_precision == 32)
1512 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1513 if (tgt_precision == 64)
1514 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1515 /*FPSCR[fprf] = undefined */
1521 FPSCR_OR_VX(fpscr_vxcvi);
1522 if ((FPSCR & fpscr_ve) == 0) {
1523 if (tgt_precision == 32) {
1524 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1525 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1528 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1529 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1531 /* FPSCR[FPRF] = undefined */
1538 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1539 if ((FPSCR & fpscr_ve) == 0) {
1540 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1541 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1542 /* FPSCR[fprf] = undefined */
1549 FPSCR_OR_VX(fpscr_vxcvi);
1550 if ((FPSCR & fpscr_ve) == 0) {
1551 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1552 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1553 /* FPSCR[fprf] = undefined */
1560 FPSCR_OR_VX(fpscr_vxcvi);
1561 if ((FPSCR & fpscr_ve) == 0) {
1562 if (tgt_precision == 32) {
1563 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1564 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1567 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1568 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1570 /* FPSCR[fprf] = undefined */
1576 # extract out raw fields of a FP number
1577 int::function::sign:unsigned64 FRS
1578 return (MASKED64(FRS, 0, 0)
1581 int::function::biased_exp:unsigned64 frs, int single
1583 return EXTRACTED64(frs, 1, 8);
1585 return EXTRACTED64(frs, 1, 11);
1586 unsigned64::function::fraction:unsigned64 frs, int single
1588 return EXTRACTED64(frs, 9, 31);
1590 return EXTRACTED64(frs, 12, 63);
1592 # a number?, each of the below return +1 or -1 (based on sign bit)
1594 int::function::is_nor:unsigned64 frs, int single
1595 int exp = biased_exp(frs, single);
1597 && exp <= (single ? 254 : 2046));
1598 int::function::is_zero:unsigned64 FRS
1599 return (MASKED64(FRS, 1, 63) == 0
1602 int::function::is_den:unsigned64 frs, int single
1603 int exp = biased_exp(frs, single);
1604 unsigned64 frac = fraction(frs, single);
1605 return (exp == 0 && frac != 0
1608 int::function::is_inf:unsigned64 frs, int single
1609 int exp = biased_exp(frs, single);
1610 int frac = fraction(frs, single);
1611 return (exp == (single ? 255 : 2047) && frac == 0
1614 int::function::is_NaN:unsigned64 frs, int single
1615 int exp = biased_exp(frs, single);
1616 int frac = fraction(frs, single);
1617 return (exp == (single ? 255 : 2047) && frac != 0
1620 int::function::is_SNaN:unsigned64 frs, int single
1621 return (is_NaN(frs, single)
1622 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1625 int::function::is_QNaN:unsigned64 frs, int single
1626 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1627 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1628 return *(double*)fra < *(double*)frb;
1629 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1630 return *(double*)fra > *(double*)frb;
1631 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1632 return *(double*)fra == *(double*)frb;
1635 # which quiet nan should become the result
1636 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1638 if (is_NaN(fra, single))
1640 else if (is_NaN(frb, single))
1641 if (instruction_is_frsp)
1642 frt = MASKED64(frb, 0, 34);
1645 else if (is_NaN(frc, single))
1647 else if (generate_qnan)
1648 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1650 error("select_qnan - default reached\n");
1654 # detect invalid operation
1655 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1657 if ((check & fpscr_vxsnan)
1658 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1659 FPSCR_OR_VX(fpscr_vxsnan);
1662 if ((check & fpscr_vxisi)
1663 && (is_inf(fra, single) && is_inf(frb, single))
1664 && ((negate && sign(fra) != sign(frb))
1665 || (!negate && sign(fra) == sign(frb)))) {
1666 /*FIXME: don't handle inf-inf VS inf+-inf */
1667 FPSCR_OR_VX(fpscr_vxisi);
1670 if ((check & fpscr_vxidi)
1671 && (is_inf(fra, single) && is_inf(frb, single))) {
1672 FPSCR_OR_VX(fpscr_vxidi);
1675 if ((check & fpscr_vxzdz)
1676 && (is_zero(fra) && is_zero(frb))) {
1677 FPSCR_OR_VX(fpscr_vxzdz);
1680 if ((check & fpscr_vximz)
1681 && (is_zero(fra) && is_inf(frb, single))) {
1682 FPSCR_OR_VX(fpscr_vximz);
1685 if ((check & fpscr_vxvc)
1686 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1687 FPSCR_OR_VX(fpscr_vxvc);
1690 if ((check & fpscr_vxsoft)) {
1691 FPSCR_OR_VX(fpscr_vxsoft);
1694 if ((check & fpscr_vxsqrt)
1696 FPSCR_OR_VX(fpscr_vxsqrt);
1699 /* if ((check && fpscr_vxcvi) {
1700 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1701 FPSCR_OR_VX(fpscr_vxcvi);
1711 # handle case of invalid operation
1712 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
1713 if (FPSCR & fpscr_ve) {
1714 /* invalid operation exception enabled */
1718 /* fpscr_FPRF unchanged */
1721 /* invalid operation exception disabled */
1722 if (instruction_is_convert_to_64bit) {
1725 else if (instruction_is_convert_to_32bit) {
1728 else { /* arrith, frsp */
1729 *frt = select_qnan(fra, frb, frc,
1730 instruction_is_frsp, 0/*generate*/, single);
1733 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1741 # I.2.4.1 Branch Instructions
1743 0.18,6.LI,30.AA,31.LK:I:t::Branch
1744 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1745 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1746 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1747 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1748 if (AA) NIA = IEA(EXTS(LI_0b00));
1749 else NIA = IEA(CIA + EXTS(LI_0b00));
1750 if (LK) LR = (spreg)CIA+4;
1751 model_branches(cpu_model(processor), 1, -1);
1753 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
1754 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1755 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1756 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1757 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1758 int M, ctr_ok, cond_ok, succeed;
1760 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1761 if (is_64bit_implementation && is_64bit_mode) M = 0;
1763 if (!BO{2}) CTR = CTR - 1;
1764 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1765 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1766 if (ctr_ok && cond_ok) {
1767 if (AA) NIA = IEA(EXTS(BD_0b00));
1768 else NIA = IEA(CIA + EXTS(BD_0b00));
1773 if (LK) LR = (spreg)IEA(CIA + 4);
1774 model_branches(cpu_model(processor), succeed, BO);
1777 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1778 reverse = EXTS(BD_0b00) < 0;
1779 } else { /* branch prediction bit not set */
1780 reverse = EXTS(BD_0b00) >= 0;
1782 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1785 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
1786 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1787 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1788 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1789 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1790 int M, ctr_ok, cond_ok, succeed;
1791 if (is_64bit_implementation && is_64bit_mode) M = 0;
1794 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1795 if (!BO{2}) CTR = CTR - 1;
1796 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1797 cond_ok = BO{0} || (CR{BI} == BO{1});
1798 if (ctr_ok && cond_ok) {
1804 if (LK) LR = (spreg)IEA(CIA + 4);
1805 model_branches(cpu_model(processor), succeed, BO);
1807 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1809 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
1810 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1811 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1812 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1813 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1814 int cond_ok, succeed;
1816 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1817 cond_ok = BO{0} || (CR{BI} == BO{1});
1819 NIA = IEA(CTR_0b00);
1824 if (LK) LR = (spreg)IEA(CIA + 4);
1825 model_branches(cpu_model(processor), succeed, BO);
1827 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1830 # I.2.4.2 System Call Instruction
1832 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
1833 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1834 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1835 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1836 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1837 model_serialize(my_index, cpu_model(processor));
1838 system_call_interrupt(processor, cia);
1841 # I.2.4.3 Condition Register Logical Instructions
1843 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1844 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1845 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1846 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1847 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1848 BLIT32(CR, BT, CR{BA} && CR{BB});
1849 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1851 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1852 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1853 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1854 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1855 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1856 BLIT32(CR, BT, CR{BA} || CR{BB});
1857 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1859 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1860 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1861 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1862 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1863 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1864 BLIT32(CR, BT, CR{BA} != CR{BB});
1865 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1867 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1868 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1869 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1870 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1871 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1872 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1873 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1875 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1876 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1877 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1878 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1879 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1880 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1881 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1883 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1884 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1885 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1886 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1887 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1888 BLIT32(CR, BT, CR{BA} == CR{BB});
1889 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1891 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1892 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1893 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1894 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1895 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1896 BLIT32(CR, BT, CR{BA} && !CR{BB});
1897 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1899 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1900 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1901 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1902 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1903 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1904 BLIT32(CR, BT, CR{BA} || !CR{BB});
1905 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1908 # I.2.4.4 Condition Register Field Instruction
1910 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1911 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1912 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1913 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1914 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1915 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1916 ppc_insn_cr1(my_index, processor, cpu_model(processor), BF, BFA);
1920 # I.3.3.2 Fixed-Point Load Instructions
1923 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1924 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1925 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1926 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1927 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1933 *rT = MEM(unsigned, EA, 1);
1935 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1937 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
1940 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1941 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1942 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1943 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1944 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1950 *rT = MEM(unsigned, EA, 1);
1952 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
1954 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
1956 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1957 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1958 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1959 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1960 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1962 if (RA == 0 || RA == RT)
1963 program_interrupt(processor, cia,
1964 illegal_instruction_program_interrupt);
1966 *rT = MEM(unsigned, EA, 1);
1968 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
1970 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1971 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1972 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1973 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1974 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1976 if (RA == 0 || RA == RT)
1977 program_interrupt(processor, cia,
1978 illegal_instruction_program_interrupt);
1980 *rT = MEM(unsigned, EA, 1);
1982 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
1984 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1985 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1986 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1987 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1988 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1994 *rT = MEM(unsigned, EA, 2);
1996 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1998 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2000 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
2001 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2002 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2003 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2004 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2010 *rT = MEM(unsigned, EA, 2);
2012 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2014 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2016 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
2017 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2018 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2019 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2020 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2022 if (RA == 0 || RA == RT)
2023 program_interrupt(processor, cia,
2024 illegal_instruction_program_interrupt);
2026 *rT = MEM(unsigned, EA, 2);
2028 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
2030 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
2031 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2032 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2033 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2034 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2036 if (RA == 0 || RA == RT)
2037 program_interrupt(processor, cia,
2038 illegal_instruction_program_interrupt);
2040 *rT = MEM(unsigned, EA, 2);
2042 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
2044 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
2045 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2046 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2047 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2048 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2054 *rT = MEM(signed, EA, 2);
2056 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2058 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2060 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
2061 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2062 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2063 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2064 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2070 *rT = MEM(signed, EA, 2);
2072 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2074 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2076 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
2077 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2078 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2079 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2080 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2082 if (RA == 0 || RA == RT)
2083 program_interrupt(processor, cia,
2084 illegal_instruction_program_interrupt);
2086 *rT = MEM(signed, EA, 2);
2087 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
2089 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
2090 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2091 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2092 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2093 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2095 if (RA == 0 || RA == RT)
2096 program_interrupt(processor, cia,
2097 illegal_instruction_program_interrupt);
2099 *rT = MEM(signed, EA, 2);
2101 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
2103 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
2104 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2105 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2106 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2107 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2113 *rT = MEM(unsigned, EA, 4);
2115 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2117 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2119 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
2120 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2121 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2122 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2123 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2129 *rT = MEM(unsigned, EA, 4);
2131 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2133 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2135 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
2136 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2137 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2138 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2139 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2141 if (RA == 0 || RA == RT)
2142 program_interrupt(processor, cia,
2143 illegal_instruction_program_interrupt);
2145 *rT = MEM(unsigned, EA, 4);
2147 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
2149 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
2150 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2151 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2152 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2153 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2155 if (RA == 0 || RA == RT)
2156 program_interrupt(processor, cia,
2157 illegal_instruction_program_interrupt);
2159 *rT = MEM(unsigned, EA, 4);
2161 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
2163 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
2166 # if (RA == 0) b = 0;
2168 # EA = b + EXTS(DS_0b00);
2169 # *rT = MEM(signed, EA, 4);
2171 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
2174 # if (RA == 0) b = 0;
2177 # *rT = MEM(signed, EA, 4);
2179 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
2181 # if (RA == 0 || RA == RT)
2182 # program_interrupt(processor, cia
2183 # illegal_instruction_program_interrupt);
2185 # *rT = MEM(signed, EA, 4);
2188 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
2191 # if (RA == 0) b = 0;
2193 # EA = b + EXTS(DS_0b00);
2194 # *rT = MEM(unsigned, EA, 8);
2196 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
2199 # if (RA == 0) b = 0;
2202 # *rT = MEM(unsigned, EA, 8);
2204 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
2206 # if (RA == 0 || RA == RT)
2207 # program_interrupt(processor, cia
2208 # illegal_instruction_program_interrupt);
2209 # EA = *rA + EXTS(DS_0b00);
2210 # *rT = MEM(unsigned, EA, 8);
2213 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
2215 # if (RA == 0 || RA == RT)
2216 # program_interrupt(processor, cia
2217 # illegal_instruction_program_interrupt);
2219 # *rT = MEM(unsigned, EA, 8);
2225 # I.3.3.3 Fixed-Point Store Instructions
2228 0.38,6.RS,11.RA,16.D:D:::Store Byte
2229 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2230 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2231 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2232 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2240 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
2242 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
2244 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
2245 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2246 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2247 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2248 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2256 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2258 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2260 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
2261 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2262 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2263 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2264 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2267 program_interrupt(processor, cia,
2268 illegal_instruction_program_interrupt);
2272 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
2274 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
2275 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2276 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2277 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2278 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2281 program_interrupt(processor, cia,
2282 illegal_instruction_program_interrupt);
2286 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
2288 0.44,6.RS,11.RA,16.D:D:::Store Half Word
2289 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2290 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2291 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2292 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2300 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
2302 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
2304 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
2305 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2306 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2307 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2308 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2316 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2318 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2320 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
2321 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2322 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2323 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2324 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2327 program_interrupt(processor, cia,
2328 illegal_instruction_program_interrupt);
2332 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
2334 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
2335 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2336 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2337 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2338 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2341 program_interrupt(processor, cia,
2342 illegal_instruction_program_interrupt);
2346 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
2348 0.36,6.RS,11.RA,16.D:D:::Store Word
2349 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2350 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2351 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2352 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2360 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
2362 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
2364 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
2365 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2366 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2367 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2368 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2376 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2378 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2380 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
2381 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2382 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2383 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2384 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2387 program_interrupt(processor, cia,
2388 illegal_instruction_program_interrupt);
2392 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
2394 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update 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
2401 program_interrupt(processor, cia,
2402 illegal_instruction_program_interrupt);
2406 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
2408 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2411 # if (RA == 0) b = 0;
2413 # EA = b + EXTS(DS_0b00);
2414 # STORE(EA, 8, *rS);
2415 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2418 # if (RA == 0) b = 0;
2421 # STORE(EA, 8, *rS);
2422 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2425 # program_interrupt(processor, cia
2426 # illegal_instruction_program_interrupt);
2427 # EA = *rA + EXTS(DS_0b00);
2428 # STORE(EA, 8, *rS);
2430 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2433 # program_interrupt(processor, cia
2434 # illegal_instruction_program_interrupt);
2436 # STORE(EA, 8, *rS);
2441 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2444 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2445 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2446 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2447 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2448 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2454 *rT = SWAP_2(MEM(unsigned, EA, 2));
2456 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2458 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2460 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2461 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2462 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2463 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2464 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2470 *rT = SWAP_4(MEM(unsigned, EA, 4));
2472 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2474 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2476 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2477 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2478 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2479 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2480 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2486 STORE(EA, 2, SWAP_2(*rS));
2488 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2490 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2492 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2493 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2494 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2495 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2496 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2502 STORE(EA, 4, SWAP_4(*rS));
2504 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2506 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2510 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2513 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
2515 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2519 # I.3.3.6 Fixed-Point Move Assist Instructions
2522 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
2524 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2526 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
2528 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2532 # I.3.3.7 Storage Synchronization Instructions
2534 # HACK: Rather than monitor addresses looking for a reason
2535 # to cancel a reservation. This code instead keeps
2536 # a copy of the data read from memory. Before performing
2537 # a store, the memory area is checked to see if it has
2539 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2540 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2541 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2542 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2543 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2550 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2551 RESERVE_DATA = MEM(unsigned, EA, 4);
2554 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2561 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2562 RESERVE_DATA = MEM(unsigned, EA, 8);
2565 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2566 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2567 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2568 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2569 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2576 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2577 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2579 CR_SET_XER_SO(0, cr_i_zero);
2582 /* ment to randomly to store, we never do! */
2583 CR_SET_XER_SO(0, 0);
2588 CR_SET_XER_SO(0, 0);
2590 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2597 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2598 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2600 CR_SET_XER_SO(0, cr_i_zero);
2603 /* ment to randomly to store, we never do */
2604 CR_SET_XER_SO(0, 0);
2609 CR_SET_XER_SO(0, 0);
2612 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2613 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2614 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2615 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2616 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2621 # I.3.3.9 Fixed-Point Arithmetic Instructions
2624 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
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_SRU, 1, 1, 0
2628 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2631 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2634 *rT = *rA + EXTS(SI);
2635 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2638 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2639 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2640 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2641 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2642 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2644 *rT = EXTS(SI) << 16;
2645 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2648 *rT = *rA + (EXTS(SI) << 16);
2649 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2652 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2653 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2654 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2655 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2656 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2659 ALU_END(*rT, 0/*CA*/, OE, Rc);
2660 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2662 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2663 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2664 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2665 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2666 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2671 ALU_END(*rT, 0/*CA*/, OE, Rc);
2672 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2674 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2675 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2676 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2677 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2678 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2681 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2682 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2684 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2685 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2686 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2687 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2688 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2691 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2692 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 1/*Rc*/);
2694 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2695 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2696 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2697 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2698 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2703 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2704 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2706 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2707 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2708 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2709 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2710 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2713 ALU_END(*rT, 1/*CA*/, OE, Rc);
2714 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2716 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2717 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2718 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2719 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2720 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2721 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2726 ALU_END(*rT, 1/*CA*/, OE, Rc);
2727 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2729 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2730 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2731 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2732 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2733 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2737 ALU_END(*rT, 1/*CA*/, OE, Rc);
2738 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2740 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2741 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2742 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2743 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2744 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2749 ALU_END(*rT, 1/*CA*/, OE, Rc);
2750 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2752 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2753 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2754 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2755 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2756 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2760 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2762 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2763 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2764 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2765 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2766 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2771 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2773 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2774 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2775 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2776 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2777 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2780 ALU_END(*rT, 1/*CA*/, OE, Rc);
2781 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2783 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2784 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2785 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2786 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2787 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2791 ALU_END(*rT, 1/*CA*/, OE, Rc);
2792 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2794 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2795 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2796 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2797 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2798 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2802 ALU_END(*rT,0/*CA*/,OE,Rc);
2803 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2805 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2806 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2807 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2808 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2809 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2810 signed_word prod = *rA * EXTS(SI);
2812 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2814 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2816 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2817 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2818 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2819 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2820 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2821 signed64 a = (signed32)(*rA);
2822 signed64 b = (signed32)(*rB);
2823 signed64 prod = a * b;
2824 signed_word t = prod;
2826 if (t != prod && OE)
2827 XER |= (xer_overflow | xer_summary_overflow);
2828 CR0_COMPARE(t, 0, Rc);
2829 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2831 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2833 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2834 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2835 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2836 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2837 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2838 signed64 a = (signed32)(*rA);
2839 signed64 b = (signed32)(*rB);
2840 signed64 prod = a * b;
2841 signed_word t = EXTRACTED64(prod, 0, 31);
2843 CR0_COMPARE(t, 0, Rc);
2844 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2846 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2848 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2849 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2850 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2851 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2852 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2853 unsigned64 a = (unsigned32)(*rA);
2854 unsigned64 b = (unsigned32)(*rB);
2855 unsigned64 prod = a * b;
2856 signed_word t = EXTRACTED64(prod, 0, 31);
2858 CR0_COMPARE(t, 0, Rc);
2859 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2861 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2863 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2864 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2865 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2866 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2867 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2868 signed64 dividend = (signed32)(*rA);
2869 signed64 divisor = (signed32)(*rB);
2870 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2871 || (dividend == 0x80000000 && divisor == -1)) {
2873 XER |= (xer_overflow | xer_summary_overflow);
2874 CR0_COMPARE(0, 0, Rc);
2877 signed64 quotent = dividend / divisor;
2879 CR0_COMPARE((signed_word)quotent, 0, Rc);
2881 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2883 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2885 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2886 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2887 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2888 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2889 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2890 unsigned64 dividend = (unsigned32)(*rA);
2891 unsigned64 divisor = (unsigned32)(*rB);
2894 XER |= (xer_overflow | xer_summary_overflow);
2895 CR0_COMPARE(0, 0, Rc);
2898 unsigned64 quotent = dividend / divisor;
2900 CR0_COMPARE((signed_word)quotent, 0, Rc);
2902 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2906 # I.3.3.10 Fixed-Point Compare Instructions
2909 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2910 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2911 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2912 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2913 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2914 if (!is_64bit_mode && L)
2915 program_interrupt(processor, cia,
2916 illegal_instruction_program_interrupt);
2919 signed_word b = EXTS(SI);
2924 CR_COMPARE(BF, a, b);
2926 ppc_insn_int1_cr(my_index, processor, cpu_model(processor), BF, rA);
2928 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2929 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2930 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2931 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2932 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2933 if (!is_64bit_mode && L)
2934 program_interrupt(processor, cia,
2935 illegal_instruction_program_interrupt);
2947 CR_COMPARE(BF, a, b);
2949 ppc_insn_int2_cr(my_index, processor, cpu_model(processor), BF, rA, rB);
2951 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2952 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2953 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2954 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2955 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2956 if (!is_64bit_mode && L)
2957 program_interrupt(processor, cia,
2958 illegal_instruction_program_interrupt);
2961 unsigned_word b = UI;
2963 a = MASKED(*rA, 32, 63);
2966 CR_COMPARE(BF, a, b);
2968 ppc_insn_int1_cr(my_index, processor, cpu_model(processor), BF, rA);
2970 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2971 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2972 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2973 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2974 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2975 if (!is_64bit_mode && L)
2976 program_interrupt(processor, cia,
2977 illegal_instruction_program_interrupt);
2982 a = MASKED(*rA, 32, 63);
2983 b = MASKED(*rB, 32, 63);
2989 CR_COMPARE(BF, a, b);
2991 ppc_insn_int2_cr(my_index, processor, cpu_model(processor), BF, rA, rB);
2995 # I.3.3.11 Fixed-Point Trap Instructions
2998 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
3000 program_interrupt(processor, cia,
3001 illegal_instruction_program_interrupt);
3003 signed_word a = *rA;
3004 signed_word b = EXTS(SI);
3005 if ((a < b && TO{0})
3007 || (a == b && TO{2})
3008 || ((unsigned_word)a < (unsigned_word)b && TO{3})
3009 || ((unsigned_word)a > (unsigned_word)b && TO{4})
3011 program_interrupt(processor, cia,
3012 trap_program_interrupt);
3015 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
3016 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3017 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3018 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3019 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3020 signed_word a = EXTENDED(*rA);
3021 signed_word b = EXTS(SI);
3022 if ((a < b && TO{0})
3024 || (a == b && TO{2})
3025 || ((unsigned_word)a < (unsigned_word)b && TO{3})
3026 || ((unsigned_word)a > (unsigned_word)b && TO{4})
3028 program_interrupt(processor, cia,
3029 trap_program_interrupt);
3031 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
3033 program_interrupt(processor, cia,
3034 illegal_instruction_program_interrupt);
3036 signed_word a = *rA;
3037 signed_word b = *rB;
3038 if ((a < b && TO{0})
3040 || (a == b && TO{2})
3041 || ((unsigned_word)a < (unsigned_word)b && TO{3})
3042 || ((unsigned_word)a > (unsigned_word)b && TO{4})
3044 program_interrupt(processor, cia,
3045 trap_program_interrupt);
3048 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
3049 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3050 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3051 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3052 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3053 signed_word a = EXTENDED(*rA);
3054 signed_word b = EXTENDED(*rB);
3055 if (TO == 12 && rA == rB) {
3056 ITRACE(trace_breakpoint, ("breakpoint\n"));
3057 cpu_halt(processor, cia, was_trap, 0);
3059 else if ((a < b && TO{0})
3061 || (a == b && TO{2})
3062 || ((unsigned_word)a < (unsigned_word)b && TO{3})
3063 || ((unsigned_word)a > (unsigned_word)b && TO{4})
3065 program_interrupt(processor, cia,
3066 trap_program_interrupt);
3069 # I.3.3.12 Fixed-Point Logical Instructions
3072 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
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, 1/*Rc*/);
3079 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 1/*Rc*/);
3081 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
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
3086 *rA = *rS & (UI << 16);
3087 CR0_COMPARE(*rA, 0, 1/*Rc*/);
3088 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 1/*Rc*/);
3090 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
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 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3098 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
3099 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3100 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3101 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3102 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3103 *rA = *rS | (UI << 16);
3104 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3106 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
3107 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3108 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3109 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3110 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3112 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3114 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
3115 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3116 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3117 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3118 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3119 *rA = *rS ^ (UI << 16);
3120 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3122 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
3123 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3124 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3125 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3126 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3128 CR0_COMPARE(*rA, 0, Rc);
3129 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3131 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
3132 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3133 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3134 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3135 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3137 CR0_COMPARE(*rA, 0, Rc);
3138 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3140 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
3141 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3142 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3143 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3144 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3146 CR0_COMPARE(*rA, 0, Rc);
3147 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3149 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
3150 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3151 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3152 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3153 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3155 CR0_COMPARE(*rA, 0, Rc);
3156 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3158 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
3159 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3160 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3161 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3162 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3164 CR0_COMPARE(*rA, 0, Rc);
3165 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3167 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
3168 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3169 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3170 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3171 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3172 # *rA = ~(*rS ^ *rB); /* A === B */
3173 # CR0_COMPARE(*rA, 0, Rc);
3175 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
3176 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3177 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3178 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3179 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3181 CR0_COMPARE(*rA, 0, Rc);
3182 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3184 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
3185 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3186 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3187 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3188 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3190 CR0_COMPARE(*rA, 0, Rc);
3191 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3193 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
3194 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3195 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3196 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3197 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3198 *rA = (signed_word)(signed8)*rS;
3199 CR0_COMPARE(*rA, 0, Rc);
3200 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3202 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
3203 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3204 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3205 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3206 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3207 *rA = (signed_word)(signed16)*rS;
3208 CR0_COMPARE(*rA, 0, Rc);
3209 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3211 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
3212 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3213 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3214 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3215 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3216 # *rA = (signed_word)(signed32)*rS;
3217 # CR0_COMPARE(*rA, 0, Rc);
3219 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
3221 # unsigned64 mask = BIT64(0);
3222 # unsigned64 source = *rS;
3223 # while (!(source & mask) && mask != 0) {
3228 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3230 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
3231 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3232 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3233 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3234 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3236 unsigned32 mask = BIT32(0);
3237 unsigned32 source = *rS;
3238 while (!(source & mask) && mask != 0) {
3243 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3247 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
3250 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
3251 # long n = (sh_5 << 4) | sh_0_4;
3252 # unsigned_word r = ROTL64(*rS, n);
3253 # long b = (mb_5 << 4) | mb_0_4;
3254 # unsigned_word m = MASK(b, 63);
3255 # signed_word result = r & m;
3257 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3259 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
3260 # long n = (sh_5 << 4) | sh_0_4;
3261 # unsigned_word r = ROTL64(*rS, n);
3262 # long e = (me_5 << 4) | me_0_4;
3263 # unsigned_word m = MASK(0, e);
3264 # signed_word result = r & m;
3266 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3268 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
3269 # long n = (sh_5 << 4) | sh_0_4;
3270 # unsigned_word r = ROTL64(*rS, n);
3271 # long b = (mb_5 << 4) | mb_0_4;
3272 # unsigned_word m = MASK(0, (64-n));
3273 # signed_word result = r & m;
3275 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3277 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
3278 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3279 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3280 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3281 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3284 unsigned32 r = ROTL32(s, n);
3285 unsigned32 m = MASK(MB+32, ME+32);
3286 signed_word result = r & m;
3288 CR0_COMPARE(result, 0, Rc);
3290 ("n=%d, s=0x%x, r=0x%x, m=0x%x, result=0x%x, cr=0x%x\n",
3291 n, s, r, m, result, CR));
3292 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3294 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
3295 # long n = MASKED(*rB, 58, 63);
3296 # unsigned_word r = ROTL64(*rS, n);
3297 # long b = (mb_5 << 4) | mb_0_4;
3298 # unsigned_word m = MASK(b, 63);
3299 # signed_word result = r & m;
3301 # CR0_COMPARE(result, 0, Rc);
3303 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
3304 # long n = MASKED(*rB, 58, 63);
3305 # unsigned_word r = ROTL64(*rS, n);
3306 # long e = (me_5 << 4) | me_0_4;
3307 # unsigned_word m = MASK(0, e);
3308 # signed_word result = r & m;
3310 # CR0_COMPARE(result, 0, Rc);
3312 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
3313 # long n = MASKED(*rB, 59, 63);
3314 # unsigned32 r = ROTL32(*rS, n);
3315 # unsigned32 m = MASK(MB+32, ME+32);
3316 # signed_word result = r & m;
3318 # CR0_COMPARE(result, 0, Rc);
3320 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
3321 # long n = (sh_5 << 4) | sh_0_4;
3322 # unsigned_word r = ROTL64(*rS, n);
3323 # long b = (mb_5 << 4) | mb_0_4;
3324 # unsigned_word m = MASK(b, (64-n));
3325 # signed_word result = (r & m) | (*rA & ~m)
3327 # CR0_COMPARE(result, 0, Rc);
3329 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
3330 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3331 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3332 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3333 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3335 unsigned32 r = ROTL32(*rS, n);
3336 unsigned32 m = MASK(MB+32, ME+32);
3337 signed_word result = (r & m) | (*rA & ~m);
3339 ITRACE(trace_alu, (": n=%d *rS=0x%x r=0x%x m=0x%x result=0x%x\n",
3340 n, *rS, r, m, result));
3341 CR0_COMPARE(result, 0, Rc);
3342 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3345 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
3347 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
3348 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3349 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3350 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3351 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3352 int n = MASKED(*rB, 59, 63);
3353 unsigned32 source = *rS;
3354 signed_word shifted;
3356 shifted = (source << n);
3360 CR0_COMPARE(shifted, 0, Rc);
3362 ("n=%d, source=0x%x, shifted=0x%x\n",
3363 n, source, shifted));
3364 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3366 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3368 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
3369 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3370 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3371 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3372 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3373 int n = MASKED(*rB, 59, 63);
3374 unsigned32 source = *rS;
3375 signed_word shifted;
3377 shifted = (source >> n);
3381 CR0_COMPARE(shifted, 0, Rc);
3383 ("n=%d, source=0x%x, shifted=0x%x\n",
3384 n, source, shifted));
3385 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3387 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3389 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3390 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3391 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3392 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3393 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3395 signed_word r = ROTL32(*rS, /*64*/32-n);
3396 signed_word m = MASK(n+32, 63);
3397 int S = MASKED(*rS, 32, 32);
3398 signed_word shifted = (r & m) | (S ? ~m : 0);
3400 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3404 CR0_COMPARE(shifted, 0, Rc);
3405 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3407 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3409 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3410 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3411 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3412 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3413 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3414 int n = MASKED(*rB, 58, 63);
3415 int shift = (n >= 31 ? 31 : n);
3416 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3417 signed32 shifted = source >> shift;
3418 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
3419 *rA = (signed_word)shifted; /* if 64bit will sign extend */
3420 if (source < 0 && (source & mask))
3424 CR0_COMPARE(shifted, 0, Rc);
3425 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3428 # I.3.3.14 Move to/from System Register Instructions
3431 0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3432 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3433 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3434 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3435 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3436 int n = (spr{5:9} << 5) | spr{0:4};
3437 if (spr{0} && IS_PROBLEM_STATE(processor))
3438 program_interrupt(processor, cia,
3439 privileged_instruction_program_interrupt);
3440 else if (!spr_is_valid(n)
3441 || spr_is_readonly(n))
3442 program_interrupt(processor, cia,
3443 illegal_instruction_program_interrupt);
3445 spreg new_val = (spr_length(n) == 64
3447 : MASKED(*rS, 32, 63));
3448 /* HACK - time base registers need to be updated immediatly */
3449 if (WITH_TIME_BASE) {
3453 cpu_set_time_base(processor,
3454 (MASKED64(cpu_get_time_base(processor), 32, 63)
3455 | INSERTED64(new_val, 0, 31)));
3458 cpu_set_time_base(processor,
3459 (MASKED64(cpu_get_time_base(processor), 0, 31)
3460 | INSERTED64(new_val, 32, 63)));
3463 cpu_set_decrementer(processor, new_val);
3474 ppc_insn_to_spr(my_index, processor, cpu_model(processor), n, rS);
3476 0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3477 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3478 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3479 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3480 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3481 int n = (spr{5:9} << 5) | spr{0:4};
3482 if (spr{0} && IS_PROBLEM_STATE(processor))
3483 program_interrupt(processor, cia,
3484 privileged_instruction_program_interrupt);
3485 else if (!spr_is_valid(n))
3486 program_interrupt(processor, cia,
3487 illegal_instruction_program_interrupt);
3489 /* HACK - some SPR's need to get their value extracted specially */
3492 ppc_insn_from_spr(my_index, processor, cpu_model(processor), rT, n);
3494 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3495 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3496 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3497 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3498 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3503 unsigned_word mask = 0;
3505 for (f = 0; f < 8; f++) {
3506 if (FXM & (0x80 >> f))
3507 mask |= (0xf << 4*(7-f));
3509 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3511 ppc_insn_mtcr(my_index, processor, cpu_model(processor), rS, FXM);
3513 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3515 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3516 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3517 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3518 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3519 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3520 *rT = (unsigned32)CR;
3521 ppc_insn_mfcr(my_index, processor, cpu_model(processor), rT);
3524 # I.4.6.2 Floating-Point Load Instructions
3527 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3528 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3529 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3530 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3531 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3537 *frT = DOUBLE(MEM(unsigned, EA, 4));
3538 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 0/*RA_is_update*/);
3540 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3541 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3542 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3543 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3544 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3550 *frT = DOUBLE(MEM(unsigned, EA, 4));
3551 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 0/*RA_is_update*/);
3553 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3554 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3555 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3556 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3557 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3560 program_interrupt(processor, cia,
3561 illegal_instruction_program_interrupt);
3563 *frT = DOUBLE(MEM(unsigned, EA, 4));
3565 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 1/*RA_is_update*/);
3567 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3568 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3569 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3570 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3571 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3574 program_interrupt(processor, cia,
3575 illegal_instruction_program_interrupt);
3577 *frT = DOUBLE(MEM(unsigned, EA, 4));
3579 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 1/*RA_is_update*/);
3581 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3582 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3583 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3584 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3585 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3591 *frT = MEM(unsigned, EA, 8);
3592 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 0/*RA_is_update*/);
3594 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3595 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3596 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3597 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3598 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3604 *frT = MEM(unsigned, EA, 8);
3605 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 0/*RA_is_update*/);
3607 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3608 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3609 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3610 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3611 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3614 program_interrupt(processor, cia,
3615 illegal_instruction_program_interrupt);
3617 *frT = MEM(unsigned, EA, 8);
3619 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 1/*RA_is_update*/);
3621 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3622 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3623 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3624 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3625 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3628 program_interrupt(processor, cia,
3629 illegal_instruction_program_interrupt);
3631 *frT = MEM(unsigned, EA, 8);
3633 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 1/*RA_is_update*/);
3637 # I.4.6.3 Floating-Point Store Instructions
3640 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3641 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3642 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3643 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3644 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3650 STORE(EA, 4, SINGLE(*frS));
3651 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 0/*RA_is_update*/);
3653 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3654 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3655 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3656 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3657 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3663 STORE(EA, 4, SINGLE(*frS));
3664 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 0/*RA_is_update*/);
3666 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3667 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3668 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3669 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3670 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3673 program_interrupt(processor, cia,
3674 illegal_instruction_program_interrupt);
3676 STORE(EA, 4, SINGLE(*frS));
3678 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 1/*RA_is_update*/);
3680 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3681 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3682 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3683 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3684 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3687 program_interrupt(processor, cia,
3688 illegal_instruction_program_interrupt);
3690 STORE(EA, 4, SINGLE(*frS));
3692 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 1/*RA_is_update*/);
3694 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3695 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3696 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3697 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3698 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3705 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 0/*RA_is_update*/);
3707 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3708 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3709 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3710 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3711 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3718 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 0/*RA_is_update*/);
3720 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3721 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3722 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3723 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3724 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3727 program_interrupt(processor, cia,
3728 illegal_instruction_program_interrupt);
3732 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 1/*RA_is_update*/);
3734 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3735 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3736 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3737 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3738 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3741 program_interrupt(processor, cia,
3742 illegal_instruction_program_interrupt);
3746 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 1/*RA_is_update*/);
3750 # I.4.6.4 Floating-Point Move Instructions
3753 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3754 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3755 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3756 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3757 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3760 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3762 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3763 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3764 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3765 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3766 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3767 *frT = *frB ^ BIT64(0);
3769 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3771 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
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
3776 *frT = *frB & ~BIT64(0);
3778 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3780 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3781 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3782 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3783 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3784 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3785 *frT = *frB | BIT64(0);
3787 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3792 # I.4.6.5 Floating-Point Arithmetic Instructions
3795 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3796 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3797 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3798 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3799 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3801 if (is_invalid_operation(processor, cia,
3803 fpscr_vxsnan | fpscr_vxisi,
3806 invalid_arithemetic_operation(processor, cia,
3808 0, /*instruction_is_frsp*/
3809 0, /*instruction_is_convert_to_64bit*/
3810 0, /*instruction_is_convert_to_32bit*/
3811 0); /*single-precision*/
3815 double s = *(double*)frA + *(double*)frB;
3819 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3821 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3822 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3823 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3824 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3825 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3827 if (is_invalid_operation(processor, cia,
3829 fpscr_vxsnan | fpscr_vxisi,
3832 invalid_arithemetic_operation(processor, cia,
3834 0, /*instruction_is_frsp*/
3835 0, /*instruction_is_convert_to_64bit*/
3836 0, /*instruction_is_convert_to_32bit*/
3837 1); /*single-precision*/
3841 float s = *(double*)frA + *(double*)frB;
3845 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3847 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3848 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3849 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3850 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3851 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3853 if (is_invalid_operation(processor, cia,
3855 fpscr_vxsnan | fpscr_vxisi,
3858 invalid_arithemetic_operation(processor, cia,
3860 0, /*instruction_is_frsp*/
3861 0, /*instruction_is_convert_to_64bit*/
3862 0, /*instruction_is_convert_to_32bit*/
3863 0); /*single-precision*/
3867 double s = *(double*)frA - *(double*)frB;
3871 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3873 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3874 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3875 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3876 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3877 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3879 if (is_invalid_operation(processor, cia,
3881 fpscr_vxsnan | fpscr_vxisi,
3884 invalid_arithemetic_operation(processor, cia,
3886 0, /*instruction_is_frsp*/
3887 0, /*instruction_is_convert_to_64bit*/
3888 0, /*instruction_is_convert_to_32bit*/
3889 1); /*single-precision*/
3893 float s = *(double*)frA - *(double*)frB;
3896 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3899 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3900 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3901 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3902 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3903 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3905 if (is_invalid_operation(processor, cia,
3907 fpscr_vxsnan | fpscr_vximz,
3910 invalid_arithemetic_operation(processor, cia,
3912 0, /*instruction_is_frsp*/
3913 0, /*instruction_is_convert_to_64bit*/
3914 0, /*instruction_is_convert_to_32bit*/
3915 0); /*single-precision*/
3919 double s = *(double*)frA * *(double*)frC;
3923 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frC, Rc);
3925 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3926 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3927 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3928 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3929 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3931 if (is_invalid_operation(processor, cia,
3933 fpscr_vxsnan | fpscr_vximz,
3936 invalid_arithemetic_operation(processor, cia,
3938 0, /*instruction_is_frsp*/
3939 0, /*instruction_is_convert_to_64bit*/
3940 0, /*instruction_is_convert_to_32bit*/
3941 1); /*single-precision*/
3945 float s = *(double*)frA * *(double*)frC;
3949 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frC, Rc);
3951 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3952 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3953 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3954 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3955 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3957 if (is_invalid_operation(processor, cia,
3959 fpscr_vxsnan | fpscr_vxzdz,
3962 invalid_arithemetic_operation(processor, cia,
3964 0, /*instruction_is_frsp*/
3965 0, /*instruction_is_convert_to_64bit*/
3966 0, /*instruction_is_convert_to_32bit*/
3967 0); /*single-precision*/
3971 double s = *(double*)frA / *(double*)frB;
3975 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3977 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3978 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3979 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3980 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3981 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3983 if (is_invalid_operation(processor, cia,
3985 fpscr_vxsnan | fpscr_vxzdz,
3988 invalid_arithemetic_operation(processor, cia,
3990 0, /*instruction_is_frsp*/
3991 0, /*instruction_is_convert_to_64bit*/
3992 0, /*instruction_is_convert_to_32bit*/
3993 1); /*single-precision*/
3997 float s = *(double*)frA / *(double*)frB;
4001 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
4003 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
4004 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4005 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4006 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4007 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4009 double product; /*HACK! - incorrectly loosing precision ... */
4010 /* compute the multiply */
4011 if (is_invalid_operation(processor, cia,
4013 fpscr_vxsnan | fpscr_vximz,
4016 invalid_arithemetic_operation(processor, cia,
4017 (unsigned64*)&product, *frA, 0, *frC,
4018 0, /*instruction_is_frsp*/
4019 0, /*instruction_is_convert_to_64bit*/
4020 0, /*instruction_is_convert_to_32bit*/
4021 0); /*single-precision*/
4025 product = *(double*)frA * *(double*)frC;
4027 /* compute the add */
4028 if (is_invalid_operation(processor, cia,
4030 fpscr_vxsnan | fpscr_vxisi,
4033 invalid_arithemetic_operation(processor, cia,
4034 frT, product, *frB, 0,
4035 0, /*instruction_is_frsp*/
4036 0, /*instruction_is_convert_to_64bit*/
4037 0, /*instruction_is_convert_to_32bit*/
4038 0); /*single-precision*/
4042 double s = product + *(double*)frB;
4046 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4048 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
4049 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4050 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4051 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4052 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4054 float product; /*HACK! - incorrectly loosing precision ... */
4055 /* compute the multiply */
4056 if (is_invalid_operation(processor, cia,
4058 fpscr_vxsnan | fpscr_vximz,
4061 invalid_arithemetic_operation(processor, cia,
4062 (unsigned64*)&product, *frA, 0, *frC,
4063 0, /*instruction_is_frsp*/
4064 0, /*instruction_is_convert_to_64bit*/
4065 0, /*instruction_is_convert_to_32bit*/
4066 0); /*single-precision*/
4070 product = *(double*)frA * *(double*)frC;
4072 /* compute the add */
4073 if (is_invalid_operation(processor, cia,
4075 fpscr_vxsnan | fpscr_vxisi,
4078 invalid_arithemetic_operation(processor, cia,
4079 frT, product, *frB, 0,
4080 0, /*instruction_is_frsp*/
4081 0, /*instruction_is_convert_to_64bit*/
4082 0, /*instruction_is_convert_to_32bit*/
4083 0); /*single-precision*/
4087 float s = product + *(double*)frB;
4088 *(double*)frT = (double)s;
4091 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4093 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
4094 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4095 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4096 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4097 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4099 double product; /*HACK! - incorrectly loosing precision ... */
4100 /* compute the multiply */
4101 if (is_invalid_operation(processor, cia,
4103 fpscr_vxsnan | fpscr_vximz,
4106 invalid_arithemetic_operation(processor, cia,
4107 (unsigned64*)&product, *frA, 0, *frC,
4108 0, /*instruction_is_frsp*/
4109 0, /*instruction_is_convert_to_64bit*/
4110 0, /*instruction_is_convert_to_32bit*/
4111 0); /*single-precision*/
4115 product = *(double*)frA * *(double*)frC;
4117 /* compute the subtract */
4118 if (is_invalid_operation(processor, cia,
4120 fpscr_vxsnan | fpscr_vxisi,
4123 invalid_arithemetic_operation(processor, cia,
4124 frT, product, *frB, 0,
4125 0, /*instruction_is_frsp*/
4126 0, /*instruction_is_convert_to_64bit*/
4127 0, /*instruction_is_convert_to_32bit*/
4128 0); /*single-precision*/
4132 double s = product - *(double*)frB;
4136 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4138 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
4139 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4140 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4141 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4142 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4144 float product; /*HACK! - incorrectly loosing precision ... */
4145 /* compute the multiply */
4146 if (is_invalid_operation(processor, cia,
4148 fpscr_vxsnan | fpscr_vximz,
4151 invalid_arithemetic_operation(processor, cia,
4152 (unsigned64*)&product, *frA, 0, *frC,
4153 0, /*instruction_is_frsp*/
4154 0, /*instruction_is_convert_to_64bit*/
4155 0, /*instruction_is_convert_to_32bit*/
4156 0); /*single-precision*/
4160 product = *(double*)frA * *(double*)frC;
4162 /* compute the subtract */
4163 if (is_invalid_operation(processor, cia,
4165 fpscr_vxsnan | fpscr_vxisi,
4168 invalid_arithemetic_operation(processor, cia,
4169 frT, product, *frB, 0,
4170 0, /*instruction_is_frsp*/
4171 0, /*instruction_is_convert_to_64bit*/
4172 0, /*instruction_is_convert_to_32bit*/
4173 0); /*single-precision*/
4177 float s = product - *(double*)frB;
4178 *(double*)frT = (double)s;
4181 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4183 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
4184 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4185 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4186 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4187 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4189 double product; /*HACK! - incorrectly loosing precision ... */
4190 /* compute the multiply */
4191 if (is_invalid_operation(processor, cia,
4193 fpscr_vxsnan | fpscr_vximz,
4196 invalid_arithemetic_operation(processor, cia,
4197 (unsigned64*)&product, *frA, 0, *frC,
4198 0, /*instruction_is_frsp*/
4199 0, /*instruction_is_convert_to_64bit*/
4200 0, /*instruction_is_convert_to_32bit*/
4201 0); /*single-precision*/
4205 product = *(double*)frA * *(double*)frC;
4207 /* compute the add */
4208 if (is_invalid_operation(processor, cia,
4210 fpscr_vxsnan | fpscr_vxisi,
4213 invalid_arithemetic_operation(processor, cia,
4214 frT, product, *frB, 0,
4215 0, /*instruction_is_frsp*/
4216 0, /*instruction_is_convert_to_64bit*/
4217 0, /*instruction_is_convert_to_32bit*/
4218 0); /*single-precision*/
4222 double s = -(product + *(double*)frB);
4226 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4228 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
4229 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4230 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4231 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4232 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4234 float product; /*HACK! - incorrectly loosing precision ... */
4235 /* compute the multiply */
4236 if (is_invalid_operation(processor, cia,
4238 fpscr_vxsnan | fpscr_vximz,
4241 invalid_arithemetic_operation(processor, cia,
4242 (unsigned64*)&product, *frA, 0, *frC,
4243 0, /*instruction_is_frsp*/
4244 0, /*instruction_is_convert_to_64bit*/
4245 0, /*instruction_is_convert_to_32bit*/
4246 0); /*single-precision*/
4250 product = *(double*)frA * *(double*)frC;
4252 /* compute the add */
4253 if (is_invalid_operation(processor, cia,
4255 fpscr_vxsnan | fpscr_vxisi,
4258 invalid_arithemetic_operation(processor, cia,
4259 frT, product, *frB, 0,
4260 0, /*instruction_is_frsp*/
4261 0, /*instruction_is_convert_to_64bit*/
4262 0, /*instruction_is_convert_to_32bit*/
4263 0); /*single-precision*/
4267 float s = -(product + *(double*)frB);
4268 *(double*)frT = (double)s;
4271 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4273 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
4274 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4275 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4276 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4277 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4279 double product; /*HACK! - incorrectly loosing precision ... */
4280 /* compute the multiply */
4281 if (is_invalid_operation(processor, cia,
4283 fpscr_vxsnan | fpscr_vximz,
4286 invalid_arithemetic_operation(processor, cia,
4287 (unsigned64*)&product, *frA, 0, *frC,
4288 0, /*instruction_is_frsp*/
4289 0, /*instruction_is_convert_to_64bit*/
4290 0, /*instruction_is_convert_to_32bit*/
4291 0); /*single-precision*/
4295 product = *(double*)frA * *(double*)frC;
4297 /* compute the subtract */
4298 if (is_invalid_operation(processor, cia,
4300 fpscr_vxsnan | fpscr_vxisi,
4303 invalid_arithemetic_operation(processor, cia,
4304 frT, product, *frB, 0,
4305 0, /*instruction_is_frsp*/
4306 0, /*instruction_is_convert_to_64bit*/
4307 0, /*instruction_is_convert_to_32bit*/
4308 0); /*single-precision*/
4312 double s = -(product - *(double*)frB);
4316 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4318 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
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
4324 float product; /*HACK! - incorrectly loosing precision ... */
4325 /* compute the multiply */
4326 if (is_invalid_operation(processor, cia,
4328 fpscr_vxsnan | fpscr_vximz,
4331 invalid_arithemetic_operation(processor, cia,
4332 (unsigned64*)&product, *frA, 0, *frC,
4333 0, /*instruction_is_frsp*/
4334 0, /*instruction_is_convert_to_64bit*/
4335 0, /*instruction_is_convert_to_32bit*/
4336 0); /*single-precision*/
4340 product = *(double*)frA * *(double*)frC;
4342 /* compute the subtract */
4343 if (is_invalid_operation(processor, cia,
4345 fpscr_vxsnan | fpscr_vxisi,
4348 invalid_arithemetic_operation(processor, cia,
4349 frT, product, *frB, 0,
4350 0, /*instruction_is_frsp*/
4351 0, /*instruction_is_convert_to_64bit*/
4352 0, /*instruction_is_convert_to_32bit*/
4353 0); /*single-precision*/
4357 float s = -(product - *(double*)frB);
4358 *(double*)frT = (double)s;
4361 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4365 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4368 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4369 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4370 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4371 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4372 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4375 unsigned64 frac_grx;
4376 /* split off cases for what to do */
4377 if (EXTRACTED64(*frB, 1, 11) < 897
4378 && EXTRACTED64(*frB, 1, 63) > 0) {
4379 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
4380 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
4382 if (EXTRACTED64(*frB, 1, 11) > 1150
4383 && EXTRACTED64(*frB, 1, 11) < 2047) {
4384 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4385 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
4387 if (EXTRACTED64(*frB, 1, 11) > 896
4388 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
4389 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
4390 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4391 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
4392 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
4393 if (EXTRACTED64(*frB, 12, 12) == 0
4394 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
4397 Disabled_Exponent_Underflow:
4398 sign = EXTRACTED64(*frB, 0, 0);
4399 if (EXTRACTED64(*frB, 1, 11) == 0) {
4401 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4403 if (EXTRACTED64(*frB, 1, 11) > 0) {
4404 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4405 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4407 Denormalize_Operand:
4408 /* G|R|X == zero from above */
4409 while (exp < -126) {
4411 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4412 | MASKED64(frac_grx, 55, 55));
4414 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4415 Round_Single(processor, sign, &exp, &frac_grx);
4416 FPSCR_SET_XX(FPSCR & fpscr_fi);
4417 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4418 *frT = INSERTED64(sign, 0, 0);
4419 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4420 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4422 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4423 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4424 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4425 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4427 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4428 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4429 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4431 /*Normalize_Operand:*/
4432 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4434 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4436 *frT = (INSERTED64(sign, 0, 0)
4437 | INSERTED64(exp + 1023, 1, 11)
4438 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4441 Enabled_Exponent_Underflow:
4443 sign = EXTRACTED64(*frB, 0, 0);
4444 if (EXTRACTED64(*frB, 1, 11) == 0) {
4446 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4448 if (EXTRACTED64(*frB, 1, 11) > 0) {
4449 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4450 frac_grx = (BIT64(0) |
4451 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4453 /*Normalize_Operand:*/
4454 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4456 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4458 Round_Single(processor, sign, &exp, &frac_grx);
4459 FPSCR_SET_XX(FPSCR & fpscr_fi);
4461 *frT = (INSERTED64(sign, 0, 0)
4462 | INSERTED64(exp + 1023, 1, 11)
4463 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4464 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4465 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4467 Disabled_Exponent_Overflow:
4469 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4470 if (EXTRACTED64(*frB, 0, 0) == 0) {
4471 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4472 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4474 if (EXTRACTED64(*frB, 0, 0) == 1) {
4475 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4476 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4479 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4480 if (EXTRACTED64(*frB, 0, 0) == 0) {
4481 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4482 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4484 if (EXTRACTED64(*frB, 0, 0) == 1) {
4485 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4486 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4489 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4490 if (EXTRACTED64(*frB, 0, 0) == 0) {
4491 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4492 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4494 if (EXTRACTED64(*frB, 0, 0) == 1) {
4495 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4496 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4499 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4500 if (EXTRACTED64(*frB, 0, 0) == 0) {
4501 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4502 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4504 if (EXTRACTED64(*frB, 0, 0) == 1) {
4505 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4506 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4509 /* FPSCR[FR] <- undefined */
4513 Enabled_Exponent_Overflow:
4514 sign = EXTRACTED64(*frB, 0, 0);
4515 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4516 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4517 Round_Single(processor, sign, &exp, &frac_grx);
4518 FPSCR_SET_XX(FPSCR & fpscr_fi);
4522 *frT = (INSERTED64(sign, 0, 0)
4523 | INSERTED64(exp + 1023, 1, 11)
4524 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4525 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4526 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4530 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4531 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4537 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4538 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4543 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4544 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4549 FPSCR_OR_VX(fpscr_vxsnan);
4550 if ((FPSCR & fpscr_ve) == 0) {
4551 *frT = (MASKED64(*frB, 0, 11)
4553 | MASKED64(*frB, 13, 34));
4554 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4560 sign = EXTRACTED64(*frB, 0, 0);
4561 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4562 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4563 Round_Single(processor, sign, &exp, &frac_grx);
4564 FPSCR_SET_XX(FPSCR & fpscr_fi);
4565 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4566 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4567 *frT = (INSERTED64(sign, 0, 0)
4568 | INSERTED64(exp + 1023, 1, 11)
4569 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4570 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4571 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4574 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
4576 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4578 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4580 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4582 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4583 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4584 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4585 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4586 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4588 convert_to_integer(processor, cia,
4590 fpscr_rn_round_towards_zero, 32);
4592 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
4594 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4595 int sign = EXTRACTED64(*frB, 0, 0);
4597 unsigned64 frac = *frB;
4598 if (frac == 0) goto Zero_Operand;
4599 if (sign == 1) frac = ~frac + 1;
4600 while (EXTRACTED64(frac, 0, 0) == 0) {
4601 /*??? do the loop 0 times if (FRB) = max negative integer */
4602 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4605 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4606 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4607 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4608 *frT = (INSERTED64(sign, 0, 0)
4609 | INSERTED64(exp + 1023, 1, 11)
4610 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4616 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4621 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
4624 # I.4.6.7 Floating-Point Compare Instructions
4627 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4628 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4629 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4630 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4631 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4634 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4635 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4636 else if (is_less_than(frA, frB))
4637 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4638 else if (is_greater_than(frA, frB))
4639 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4641 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4643 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4644 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4645 FPSCR_OR_VX(fpscr_vxsnan);
4647 ppc_insn_fp2_cr(my_index, processor, cpu_model(processor), BF, frA, frB);
4649 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4650 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4651 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4652 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4653 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4656 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4657 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4658 else if (is_less_than(frA, frB))
4659 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4660 else if (is_greater_than(frA, frB))
4661 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4663 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4665 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4666 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4667 FPSCR_OR_VX(fpscr_vxsnan);
4668 if ((FPSCR & fpscr_ve) == 0)
4669 FPSCR_OR_VX(fpscr_vxvc);
4671 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4672 FPSCR_OR_VX(fpscr_vxvc);
4675 ppc_insn_fp2_cr(my_index, processor, cpu_model(processor), BF, frA, frB);
4679 # I.4.6.8 Floating-Point Status and Control Register Instructions
4682 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4684 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4686 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4688 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4690 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4692 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4696 # I.A.1.1 Floating-Point Store Instruction
4698 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4701 # I.A.1.2 Floating-Point Arithmetic Instructions
4704 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
4706 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4708 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
4710 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4713 # I.A.1.3 Floating-Point Select Instruction
4716 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4720 # II.3.2 Cache Management Instructions
4723 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4724 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4725 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4726 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4727 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4728 /* blindly flush all instruction cache entries */
4729 #if WITH_IDECODE_CACHE_SIZE
4730 cpu_flush_icache(processor);
4733 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4735 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4737 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4738 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4739 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4740 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4741 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4742 cpu_synchronize_context(processor);
4743 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
4747 # II.3.2.2 Data Cache Instructions
4750 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4751 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4752 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4753 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4754 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4755 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4757 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4759 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4761 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4762 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4763 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4764 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4765 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4766 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4768 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4770 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4772 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4773 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4774 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4775 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4776 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4777 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4779 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4781 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4783 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4784 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4785 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4786 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4787 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4788 TRACE(trace_tbd,("Data Cache Block Store\n"));
4790 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4792 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4794 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4795 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4796 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4797 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4798 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4799 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4801 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4803 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4806 # II.3.3 Enforce In-order Execution of I/O Instruction
4809 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4810 /* Since this model has no instruction overlap
4811 this instruction need do nothing */
4814 # II.4.1 Time Base Instructions
4817 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4818 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4819 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4820 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4821 int n = (tbr{5:9} << 5) | tbr{0:4};
4823 if (is_64bit_implementation) *rT = TB;
4824 else *rT = EXTRACTED64(TB, 32, 63);
4826 else if (n == 269) {
4827 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4828 else *rT = EXTRACTED64(TB, 0, 31);
4831 program_interrupt(processor, cia,
4832 illegal_instruction_program_interrupt);
4836 # III.2.3.1 System Linkage Instructions
4839 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4840 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4841 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4842 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4843 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4844 if (IS_PROBLEM_STATE(processor)) {
4845 program_interrupt(processor, cia,
4846 privileged_instruction_program_interrupt);
4849 MSR = (MASKED(SRR1, 0, 32)
4850 | MASKED(SRR1, 37, 41)
4851 | MASKED(SRR1, 48, 63));
4852 NIA = MASKED(SRR0, 0, 61);
4853 cpu_synchronize_context(processor);
4857 # III.3.4.1 Move to/from System Register Instructions
4860 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
4861 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
4862 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4863 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4864 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4865 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4866 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4867 if (IS_PROBLEM_STATE(processor))
4868 program_interrupt(processor, cia,
4869 privileged_instruction_program_interrupt);
4873 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4874 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4875 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4876 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4877 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4878 if (IS_PROBLEM_STATE(processor))
4879 program_interrupt(processor, cia,
4880 privileged_instruction_program_interrupt);
4886 # III.4.11.1 Cache Management Instructions
4889 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4890 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4891 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4892 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4893 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4894 if (IS_PROBLEM_STATE(processor))
4895 program_interrupt(processor, cia,
4896 privileged_instruction_program_interrupt);
4898 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4901 # III.4.11.2 Segment Register Manipulation Instructions
4904 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4905 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4906 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4907 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4908 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4909 if (IS_PROBLEM_STATE(processor))
4910 program_interrupt(processor, cia,
4911 privileged_instruction_program_interrupt);
4915 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4916 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4917 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4918 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4919 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4920 if (IS_PROBLEM_STATE(processor))
4921 program_interrupt(processor, cia,
4922 privileged_instruction_program_interrupt);
4924 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4926 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4927 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4928 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4929 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4930 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4931 if (IS_PROBLEM_STATE(processor))
4932 program_interrupt(processor, cia,
4933 privileged_instruction_program_interrupt);
4937 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4938 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4939 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4940 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4941 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4942 if (IS_PROBLEM_STATE(processor))
4943 program_interrupt(processor, cia,
4944 privileged_instruction_program_interrupt);
4946 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4950 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4953 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4955 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4957 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4959 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4961 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4965 # III.A.1.2 External Access Instructions
4968 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4970 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed