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 #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \
79 if (CURRENT_MODEL_ISSUE > 0) { \
81 ppc_insn_int(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \
83 ppc_insn_int_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
87 #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \
89 if (CURRENT_MODEL_ISSUE > 0) \
90 ppc_insn_int_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
93 #define PPC_INSN_CR(OUT_MASK, IN_MASK) \
95 if (CURRENT_MODEL_ISSUE > 0) \
96 ppc_insn_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \
99 #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \
101 if (CURRENT_MODEL_ISSUE > 0) { \
103 ppc_insn_float(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \
105 ppc_insn_float_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
109 #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \
111 if (CURRENT_MODEL_ISSUE > 0) \
112 ppc_insn_float_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
115 #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \
117 if (CURRENT_MODEL_ISSUE > 0) \
118 ppc_insn_int_float(my_index, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \
121 #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \
123 if (CURRENT_MODEL_ISSUE > 0) \
124 ppc_insn_from_spr(my_index, cpu_model(processor), INT_MASK, SPR); \
127 #define PPC_INSN_TO_SPR(INT_MASK, SPR) \
129 if (CURRENT_MODEL_ISSUE > 0) \
130 ppc_insn_to_spr(my_index, cpu_model(processor), INT_MASK, SPR); \
133 #define PPC_INSN_MFCR(INT_MASK) \
135 if (CURRENT_MODEL_ISSUE > 0) \
136 ppc_insn_mfcr(my_index, cpu_model(processor), INT_MASK); \
139 #define PPC_INSN_MTCR(INT_MASK, FXM) \
141 if (CURRENT_MODEL_ISSUE > 0) \
142 ppc_insn_mtcr(my_index, cpu_model(processor), INT_MASK, FXM); \
146 typedef enum _ppc_function_unit {
147 PPC_UNIT_BAD, /* unknown function unit */
148 PPC_UNIT_IU, /* integer unit (601/603 style) */
149 PPC_UNIT_SRU, /* system register unit (601/603 style) */
150 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
151 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
152 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
153 PPC_UNIT_FPU, /* floating point unit */
154 PPC_UNIT_LSU, /* load/store unit */
155 PPC_UNIT_BPU, /* branch unit */
156 nr_ppc_function_units
159 /* Structure to hold timing information on a per instruction basis */
161 ppc_function_unit first_unit; /* first functional unit this insn could use */
162 ppc_function_unit second_unit; /* second functional unit this insn could use */
163 signed16 issue; /* # cycles before function unit can process other insns */
164 signed16 done; /* # cycles before insn is done */
165 unsigned32 flags; /* any flags that are needed */
168 /* Register mappings in status masks */
169 #define PPC_CR_REG 0 /* start of CR0 .. CR7 */
170 #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */
172 #define PPC_NO_SPR (-1) /* flag for no SPR register */
174 /* Return if 1 bit set */
175 #define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0)
177 /* Structure for each functional unit that is busy */
178 typedef struct _model_busy model_busy;
180 model_busy *next; /* next function unit */
181 ppc_function_unit unit; /* function unit name */
182 unsigned32 int_busy; /* int registers that are busy */
183 unsigned32 fp_busy; /* floating point registers that are busy */
184 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
185 signed16 spr_busy; /* SPR register that is busy or PPC_NO_SPR */
186 signed16 issue; /* # of cycles until unit can accept another insn */
187 signed16 done; /* # of cycles until insn is done */
188 signed16 nr_writebacks; /* # of registers this unit writes back */
191 /* Structure to hold the current state information for the simulated CPU model */
193 cpu *processor; /* point back to processor */
194 const char *name; /* model name */
195 const model_time *timing; /* timing information */
196 model_busy busy_head; /* dummy entry to head list of busy function units */
197 model_busy *busy_tail; /* tail of list of busy function units */
198 model_busy *free_list; /* list of model_busy structs not in use */
199 count_type nr_cycles; /* # cycles */
200 count_type nr_branches; /* # branches */
201 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
202 count_type nr_branch_predict_trues; /* # branches predicted correctly */
203 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
204 count_type nr_branch_conditional[32]; /* # of each type of bc */
205 count_type nr_mtcrf_crs[9]; /* # of CR's moved in a mtcrf instruction */
206 count_type nr_stalls_data; /* # of stalls for data */
207 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
208 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
209 count_type nr_stalls_writeback; /* # of stalls waiting for a writeback slot */
210 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
211 int max_nr_writebacks; /* max # of writeback slots available */
212 unsigned32 int_busy; /* int registers that are busy */
213 unsigned32 fp_busy; /* floating point registers that are busy */
214 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
215 unsigned8 spr_busy[nr_of_sprs]; /* SPR registers that are busy */
216 unsigned8 busy[nr_ppc_function_units]; /* whether a function is busy or not */
219 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
220 "unknown functional unit instruction",
221 "integer functional unit instruction",
222 "system register functional unit instruction",
223 "1st single cycle integer functional unit instruction",
224 "2nd single cycle integer functional unit instruction",
225 "multiple cycle integer functional unit instruction",
226 "floating point functional unit instruction",
227 "load/store functional unit instruction",
228 "branch functional unit instruction",
231 STATIC_MODEL const char *const ppc_branch_conditional_name[32] = {
232 "branch if --CTR != 0 and condition is FALSE", /* 0000y */
233 "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
234 "branch if --CTR == 0 and condition is FALSE", /* 0001y */
235 "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
236 "branch if the condition is FALSE", /* 001zy */
237 "branch if the condition is FALSE, reverse branch likely",
238 "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */
239 "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
240 "branch if --CTR != 0 and condition is TRUE", /* 0100y */
241 "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
242 "branch if --CTR == 0 and condition is TRUE", /* 0101y */
243 "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
244 "branch if the condition is TRUE", /* 011zy */
245 "branch if the condition is TRUE, reverse branch likely",
246 "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */
247 "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
248 "branch if --CTR != 0", /* 1z00y */
249 "branch if --CTR != 0, reverse branch likely",
250 "branch if --CTR == 0", /* 1z01y */
251 "branch if --CTR == 0, reverse branch likely",
252 "branch always", /* 1z1zz */
253 "branch always (ignored bit 5 set to 1)",
254 "branch always (ignored bit 4 set to 1)", /* 1z1zz */
255 "branch always (ignored bits 4,5 set to 1)",
256 "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */
257 "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
258 "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */
259 "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
260 "branch always (ignored bit 1 set to 1)", /* 1z1zz */
261 "branch always (ignored bits 1,5 set to 1)",
262 "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */
263 "branch always (ignored bits 1,4,5 set to 1)",
266 STATIC_MODEL const char *const ppc_nr_mtcrf_crs[9] = {
267 "mtcrf moving 0 CRs",
269 "mtcrf moving 2 CRs",
270 "mtcrf moving 3 CRs",
271 "mtcrf moving 4 CRs",
272 "mtcrf moving 5 CRs",
273 "mtcrf moving 6 CRs",
274 "mtcrf moving 7 CRs",
275 "mtcrf moving all CRs",
278 # Trace releasing resources
279 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
281 TRACE(trace_model,("done, %s, %d writeback%s\n", ppc_function_unit_name[busy->unit],
282 busy->nr_writebacks, busy->nr_writebacks == 1 ? "" : "s"));
283 if (busy->int_busy) {
284 for(i = 0; i < 32; i++) {
285 if (((1 << i) & busy->int_busy) != 0) {
286 TRACE(trace_model, ("Register r%d is now available.\n", i));
291 for(i = 0; i < 32; i++) {
292 if (((1 << i) & busy->fp_busy) != 0) {
293 TRACE(trace_model, ("Register f%d is now available.\n", i));
297 if (busy->cr_fpscr_busy) {
298 for(i = 0; i < 8; i++) {
299 if (((1 << i) & busy->cr_fpscr_busy) != 0) {
300 TRACE(trace_model, ("Register cr%d is now available.\n", i));
303 if (busy->cr_fpscr_busy & 0x100)
304 TRACE(trace_model, ("Register fpscr is now available.\n"));
306 if (busy->spr_busy != PPC_NO_SPR)
307 TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
309 # Trace making registers busy
310 void::model-static::model_trace_make_busy:model_data *model_ptr, unsigned32 int_mask, unsigned32 fp_mask, unsigned32 cr_mask
313 for(i = 0; i < 32; i++) {
314 if (((1 << i) & int_mask) != 0) {
315 TRACE(trace_model, ("Register r%d is now busy.\n", i));
320 for(i = 0; i < 32; i++) {
321 if (((1 << i) & fp_mask) != 0) {
322 TRACE(trace_model, ("Register f%d is now busy.\n", i));
327 for(i = 0; i < 8; i++) {
328 if (((1 << i) & cr_mask) != 0) {
329 TRACE(trace_model, ("Register cr%d is now busy.\n", i));
334 # Trace waiting for registers to become available
335 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
338 int_busy &= model_ptr->int_busy;
339 for(i = 0; i < 32; i++) {
340 if (((1 << i) & int_busy) != 0) {
341 TRACE(trace_model, ("Waiting for register r%d.\n", i));
346 fp_busy &= model_ptr->fp_busy;
347 for(i = 0; i < 32; i++) {
348 if (((1 << i) & fp_busy) != 0) {
349 TRACE(trace_model, ("Waiting for register f%d.\n", i));
353 if (cr_or_fpscr_busy) {
354 cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
355 for(i = 0; i < 8; i++) {
356 if (((1 << i) & cr_or_fpscr_busy) != 0) {
357 TRACE(trace_model, ("Waiting for register cr%d.\n", i));
360 if (cr_or_fpscr_busy & 0x100)
361 TRACE(trace_model, ("Waiting for register fpscr.\n"));
363 if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
364 TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
366 # Advance state to next cycle, releasing any registers allocated
367 void::model-internal::model_new_cycle:model_data *model_ptr
368 model_busy *cur_busy = model_ptr->busy_head.next;
369 model_busy *free_list = model_ptr->free_list;
370 model_busy *busy_tail = &model_ptr->busy_head;
371 int nr_writebacks = model_ptr->max_nr_writebacks;
374 model_ptr->nr_cycles++;
375 TRACE(trace_model,("New cycle %lu\n", (unsigned long)model_ptr->nr_cycles));
376 for ( ; cur_busy; cur_busy = next) {
377 next = cur_busy->next;
378 if (--cur_busy->done <= 0) { /* function unit done, release registers if we have writeback slots */
379 nr_writebacks -= cur_busy->nr_writebacks;
380 if (nr_writebacks >= 0) {
381 model_ptr->int_busy &= ~cur_busy->int_busy;
382 model_ptr->fp_busy &= ~cur_busy->fp_busy;
383 model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
384 if (cur_busy->spr_busy != PPC_NO_SPR)
385 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
387 if (WITH_TRACE && ppc_trace[trace_model])
388 model_trace_release(model_ptr, cur_busy);
390 model_ptr->busy[cur_busy->unit] = 0;
391 cur_busy->next = free_list;
392 free_list = cur_busy;
394 else { /* writeback slots not available */
395 TRACE(trace_model,("%d writeback slot%s not available for %s\n",
396 cur_busy->nr_writebacks,
397 cur_busy->nr_writebacks == 1 ? " is" : "s are",
398 ppc_function_unit_name[cur_busy->unit]));
399 cur_busy->done++; /* undo -- above */
400 model_ptr->nr_stalls_writeback++;
401 busy_tail->next = cur_busy;
402 busy_tail = cur_busy;
405 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
406 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
407 model_ptr->busy[cur_busy->unit] = 0;
408 busy_tail->next = cur_busy;
409 busy_tail = cur_busy;
412 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
413 ppc_function_unit_name[cur_busy->unit],
416 busy_tail->next = cur_busy;
417 busy_tail = cur_busy;
421 busy_tail->next = (model_busy *)0;
422 model_ptr->busy_tail = busy_tail;
423 model_ptr->free_list = free_list;
425 # Mark a function unit as busy, return the busy structure
426 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
429 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
431 if (!model_ptr->free_list) {
432 busy = ZALLOC(model_busy);
435 busy = model_ptr->free_list;
436 model_ptr->free_list = busy->next;
437 busy->next = (model_busy *)0;
440 busy->cr_fpscr_busy = 0;
441 busy->nr_writebacks = 0;
447 busy->spr_busy = PPC_NO_SPR;
448 model_ptr->busy_tail->next = busy;
449 model_ptr->busy_tail = busy;
450 model_ptr->busy[unit] = 1;
451 model_ptr->nr_units[unit]++;
454 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
455 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
456 ppc_function_unit first_unit = time_ptr->first_unit;
457 ppc_function_unit second_unit = time_ptr->second_unit;
458 int stall_increment = 0;
461 if (!model_ptr->busy[first_unit])
462 return model_make_busy(model_ptr, first_unit,
463 model_ptr->timing[index].issue,
464 model_ptr->timing[index].done);
466 if (!model_ptr->busy[second_unit])
467 return model_make_busy(model_ptr, second_unit,
468 model_ptr->timing[index].issue,
469 model_ptr->timing[index].done);
471 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
472 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
474 model_new_cycle(model_ptr);
477 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
478 void::model-function::model_serialize:itable_index index, model_data *model_ptr
479 while (model_ptr->busy_head.next) {
480 TRACE(trace_model,("waiting for pipeline to empty\n"));
481 model_ptr->nr_stalls_serialize++;
482 model_new_cycle(model_ptr);
484 (void) model_make_busy(model_ptr,
485 model_ptr->timing[index].first_unit,
486 model_ptr->timing[index].issue,
487 model_ptr->timing[index].done);
489 # Wait for a CR to become unbusy
490 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
494 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
497 cr_mask = (1 << cr_var);
498 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
499 TRACE(trace_model,("waiting for CR %d\n", cr_var));
500 model_ptr->nr_stalls_data++;
501 model_new_cycle(model_ptr);
504 # Schedule an instruction that takes integer input registers and produces output registers
505 void::model-function::ppc_insn_int:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
506 const unsigned32 int_mask = out_mask | in_mask;
507 model_busy *busy_ptr;
509 if ((model_ptr->int_busy & int_mask) != 0) {
510 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
512 while ((model_ptr->int_busy & int_mask) != 0) {
513 if (WITH_TRACE && ppc_trace[trace_model])
514 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
516 model_ptr->nr_stalls_data++;
517 model_new_cycle(model_ptr);
521 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
522 model_ptr->int_busy |= out_mask;
523 busy_ptr->int_busy |= out_mask;
525 busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
527 if (WITH_TRACE && ppc_trace[trace_model])
528 model_trace_make_busy(model_ptr, out_mask, 0, 0);
530 # Schedule an instruction that takes integer input registers and produces output registers & sets a CR register
531 void::model-function::ppc_insn_int_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask
532 const unsigned32 int_mask = out_mask | in_mask;
533 model_busy *busy_ptr;
535 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
536 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
538 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
539 if (WITH_TRACE && ppc_trace[trace_model])
540 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
542 model_ptr->nr_stalls_data++;
543 model_new_cycle(model_ptr);
547 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
548 model_ptr->int_busy |= out_mask;
549 busy_ptr->int_busy |= out_mask;
550 model_ptr->cr_fpscr_busy |= cr_mask;
551 busy_ptr->cr_fpscr_busy |= cr_mask;
553 busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
556 busy_ptr->nr_writebacks++;
558 if (WITH_TRACE && ppc_trace[trace_model])
559 model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
562 # Schedule an instruction that takes CR input registers and produces output CR registers
563 void::model-function::ppc_insn_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
564 const unsigned32 cr_mask = out_mask | in_mask;
565 model_busy *busy_ptr;
567 if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
568 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
570 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
571 if (WITH_TRACE && ppc_trace[trace_model])
572 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
574 model_ptr->nr_stalls_data++;
575 model_new_cycle(model_ptr);
579 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
580 model_ptr->cr_fpscr_busy |= out_mask;
581 busy_ptr->cr_fpscr_busy |= out_mask;
583 busy_ptr->nr_writebacks = 1;
585 if (WITH_TRACE && ppc_trace[trace_model])
586 model_trace_make_busy(model_ptr, 0, 0, out_mask);
589 # Schedule an instruction that takes floating point input registers and produces an output fp register
590 void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
591 const unsigned32 fp_mask = out_mask | in_mask;
592 model_busy *busy_ptr;
594 if ((model_ptr->fp_busy & fp_mask) != 0) {
595 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
597 while ((model_ptr->fp_busy & fp_mask) != 0) {
598 if (WITH_TRACE && ppc_trace[trace_model])
599 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
601 model_ptr->nr_stalls_data++;
602 model_new_cycle(model_ptr);
606 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
607 model_ptr->fp_busy |= out_mask;
608 busy_ptr->fp_busy |= out_mask;
609 busy_ptr->nr_writebacks = 1;
610 if (WITH_TRACE && ppc_trace[trace_model])
611 model_trace_make_busy(model_ptr, 0, out_mask, 0);
614 # Schedule an instruction that takes floating point input registers and produces an output fp register & sets a CR reg
615 void::model-function::ppc_insn_float_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask
616 const unsigned32 fp_mask = out_mask | in_mask;
617 model_busy *busy_ptr;
619 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
620 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
622 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
623 if (WITH_TRACE && ppc_trace[trace_model])
624 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
626 model_ptr->nr_stalls_data++;
627 model_new_cycle(model_ptr);
631 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
632 model_ptr->fp_busy |= out_mask;
633 busy_ptr->fp_busy |= out_mask;
634 model_ptr->cr_fpscr_busy |= cr_mask;
635 busy_ptr->cr_fpscr_busy |= cr_mask;
636 busy_ptr->nr_writebacks = (cr_mask) ? 2 : 1;
637 if (WITH_TRACE && ppc_trace[trace_model])
638 model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
641 # Schedule an instruction that takes both int/float input registers and produces output int/float registers
642 void::model-function::ppc_insn_int_float:itable_index index, model_data *model_ptr, const unsigned32 out_int_mask, const unsigned32 out_fp_mask, const unsigned32 in_int_mask, const unsigned32 in_fp_mask
643 const unsigned32 int_mask = out_int_mask | in_int_mask;
644 const unsigned32 fp_mask = out_fp_mask | in_fp_mask;
645 model_busy *busy_ptr;
647 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
648 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
650 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
651 if (WITH_TRACE && ppc_trace[trace_model])
652 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
654 model_ptr->nr_stalls_data++;
655 model_new_cycle(model_ptr);
658 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
659 model_ptr->int_busy |= out_int_mask;
660 busy_ptr->int_busy |= out_int_mask;
661 model_ptr->fp_busy |= out_fp_mask;
662 busy_ptr->fp_busy |= out_fp_mask;
663 busy_ptr->nr_writebacks = ((out_int_mask) ? 1 : 0) + ((out_fp_mask) ? 1 : 0);
664 if (WITH_TRACE && ppc_trace[trace_model])
665 model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0);
669 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
670 void::model-function::ppc_insn_from_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
671 model_busy *busy_ptr;
673 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
674 if (WITH_TRACE && ppc_trace[trace_model])
675 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
677 model_ptr->nr_stalls_data++;
678 model_new_cycle(model_ptr);
681 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
682 model_ptr->int_busy |= int_mask;
683 busy_ptr->int_busy |= int_mask;
684 busy_ptr->nr_writebacks = 1;
685 if (WITH_TRACE && ppc_trace[trace_model])
686 model_trace_make_busy(model_ptr, int_mask, 0, 0);
688 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
689 void::model-function::ppc_insn_to_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
690 model_busy *busy_ptr;
692 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
693 if (WITH_TRACE && ppc_trace[trace_model])
694 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
696 model_ptr->nr_stalls_data++;
697 model_new_cycle(model_ptr);
700 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
701 busy_ptr->spr_busy = nSPR;
702 model_ptr->spr_busy[nSPR] = 1;
703 busy_ptr->nr_writebacks = 1;
704 TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));
706 # Schedule a MFCR instruction that moves the CR into an integer regsiter
707 void::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, unsigned32 int_mask
708 const unsigned32 cr_mask = 0xff;
709 model_busy *busy_ptr;
711 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
712 if (WITH_TRACE && ppc_trace[trace_model])
713 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
715 model_ptr->nr_stalls_data++;
716 model_new_cycle(model_ptr);
719 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
720 model_ptr->int_busy |= int_mask;
721 busy_ptr->int_busy |= int_mask;
722 busy_ptr->nr_writebacks = 1;
723 if (WITH_TRACE && ppc_trace[trace_model])
724 model_trace_make_busy(model_ptr, int_mask, 0, 0);
726 # Schedule a MTCR instruction that moves an integer register into the CR
727 void::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, unsigned32 int_mask, unsigned FXM
730 unsigned32 cr_mask = 0;
731 const model_time *normal_time = &model_ptr->timing[index];
732 static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 };
733 model_busy *busy_ptr;
735 for (f = 0; f < 8; f++) {
736 if (FXM & (0x80 >> f)) {
742 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
743 if (WITH_TRACE && ppc_trace[trace_model])
744 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
746 model_ptr->nr_stalls_data++;
747 model_new_cycle(model_ptr);
750 /* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */
751 if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) {
752 normal_time = &ppc604_1bit_time;
755 busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
756 busy_ptr->cr_fpscr_busy |= cr_mask;
757 model_ptr->cr_fpscr_busy |= cr_mask;
758 model_ptr->nr_mtcrf_crs[nr_crs]++;
759 busy_ptr->nr_writebacks = 1;
760 if (WITH_TRACE && ppc_trace[trace_model])
761 model_trace_make_busy(model_ptr, 0, 0, cr_mask);
763 model_data *::model-function::model_create:cpu *processor
764 model_data *model_ptr = ZALLOC(model_data);
765 model_ptr->name = model_name[CURRENT_MODEL];
766 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
767 model_ptr->processor = processor;
768 model_ptr->nr_cycles = 1;
769 model_ptr->busy_tail = &model_ptr->busy_head;
770 switch (CURRENT_MODEL) {
771 case MODEL_ppc601: model_ptr->max_nr_writebacks = 1; break; /* ??? */
772 case MODEL_ppc603: model_ptr->max_nr_writebacks = 2; break;
773 case MODEL_ppc603e: model_ptr->max_nr_writebacks = 2; break;
774 case MODEL_ppc604: model_ptr->max_nr_writebacks = 2; break;
775 default: error ("Unknown model %d\n", CURRENT_MODEL);
779 void::model-function::model_init:model_data *model_ptr
781 void::model-function::model_halt:model_data *model_ptr
782 /* Let pipeline drain */
783 while (model_ptr->busy_head.next)
784 model_new_cycle(model_ptr);
786 model_print *::model-function::model_mon_info:model_data *model_ptr
793 head = tail = ZALLOC(model_print);
794 tail->count = model_ptr->nr_cycles;
795 tail->name = "cycle";
796 tail->suffix_plural = "s";
797 tail->suffix_singular = "";
799 if (model_ptr->nr_stalls_data) {
800 tail->next = ZALLOC(model_print);
802 tail->count = model_ptr->nr_stalls_data;
803 tail->name = "stall";
804 tail->suffix_plural = "s waiting for data";
805 tail->suffix_singular = " waiting for data";
808 if (model_ptr->nr_stalls_unit) {
809 tail->next = ZALLOC(model_print);
811 tail->count = model_ptr->nr_stalls_unit;
812 tail->name = "stall";
813 tail->suffix_plural = "s waiting for a function unit";
814 tail->suffix_singular = " waiting for a function unit";
817 if (model_ptr->nr_stalls_serialize) {
818 tail->next = ZALLOC(model_print);
820 tail->count = model_ptr->nr_stalls_serialize;
821 tail->name = "stall";
822 tail->suffix_plural = "s waiting for serialization";
823 tail->suffix_singular = " waiting for serialization";
826 if (model_ptr->nr_stalls_writeback) {
827 tail->next = ZALLOC(model_print);
829 tail->count = model_ptr->nr_stalls_writeback;
831 tail->suffix_plural = "times a writeback slot was unavilable";
832 tail->suffix_singular = "time a writeback was unavilable";
835 if (model_ptr->nr_branches) {
836 tail->next = ZALLOC(model_print);
838 tail->count = model_ptr->nr_branches;
839 tail->name = "branch";
840 tail->suffix_plural = "es";
841 tail->suffix_singular = "";
844 if (model_ptr->nr_branches_fallthrough) {
845 tail->next = ZALLOC(model_print);
847 tail->count = model_ptr->nr_branches_fallthrough;
848 tail->name = "conditional branch";
849 tail->suffix_plural = "es fell through";
850 tail->suffix_singular = " fell through";
853 if (model_ptr->nr_branch_predict_trues) {
854 tail->next = ZALLOC(model_print);
856 tail->count = model_ptr->nr_branch_predict_trues;
857 tail->name = "successful branch prediction";
858 tail->suffix_plural = "s";
859 tail->suffix_singular = "";
862 if (model_ptr->nr_branch_predict_falses) {
863 tail->next = ZALLOC(model_print);
865 tail->count = model_ptr->nr_branch_predict_falses;
866 tail->name = "unsuccessful branch prediction";
867 tail->suffix_plural = "s";
868 tail->suffix_singular = "";
871 for (j = 0; j < (sizeof(ppc_branch_conditional_name) / sizeof(ppc_branch_conditional_name[0])) ; j++) {
872 if (model_ptr->nr_branch_conditional[j]) {
873 tail->next = ZALLOC(model_print);
875 tail->count = model_ptr->nr_branch_conditional[j];
876 tail->name = ppc_branch_conditional_name[j];
877 tail->suffix_plural = " conditional branches";
878 tail->suffix_singular = " conditional branch";
882 for (j = 0; j < 9; j++) {
883 if (model_ptr->nr_mtcrf_crs[j]) {
884 tail->next = ZALLOC(model_print);
886 tail->count = model_ptr->nr_mtcrf_crs[j];
887 tail->name = ppc_nr_mtcrf_crs[j];
888 tail->suffix_plural = " instructions";
889 tail->suffix_singular = " instruction";
894 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
895 if (model_ptr->nr_units[i]) {
896 nr_insns += model_ptr->nr_units[i];
897 tail->next = ZALLOC(model_print);
899 tail->count = model_ptr->nr_units[i];
900 tail->name = ppc_function_unit_name[i];
901 tail->suffix_plural = "s";
902 tail->suffix_singular = "";
906 tail->next = ZALLOC(model_print);
908 tail->count = nr_insns;
909 tail->name = "instruction";
910 tail->suffix_plural = "s that were accounted for in timing info";
911 tail->suffix_singular = " that was accounted for in timing info";
913 tail->next = (model_print *)0;
916 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
918 model_print *next = ptr->next;
923 void::model-function::model_branches:model_data *model_ptr, int failed, int conditional
924 model_ptr->nr_units[PPC_UNIT_BPU]++;
926 model_ptr->nr_branches_fallthrough++;
928 model_ptr->nr_branches++;
929 if (conditional >= 0)
930 model_ptr->nr_branch_conditional[conditional]++;
931 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
933 void::model-function::model_branch_predict:model_data *model_ptr, int success
935 model_ptr->nr_branch_predict_trues++;
937 model_ptr->nr_branch_predict_falses++;
940 # The following (illegal) instruction is `known' by gen and is
941 # called when ever an illegal instruction is encountered
943 program_interrupt(processor, cia,
944 illegal_instruction_program_interrupt);
948 # The following (floating point unavailable) instruction is `known' by gen
949 # and is called when ever an a floating point instruction is to be
950 # executed but floating point is make unavailable by the MSR
951 ::internal::floating_point_unavailable
952 floating_point_unavailable_interrupt(processor, cia);
957 # Floating point support functions
960 # Convert 32bit single to 64bit double
961 unsigned64::function::DOUBLE:unsigned32 WORD
963 if (EXTRACTED32(WORD, 1, 8) > 0
964 && EXTRACTED32(WORD, 1, 8) < 255) {
965 /* normalized operand */
966 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
967 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
968 | INSERTED64(not_word_1_1, 2, 2)
969 | INSERTED64(not_word_1_1, 3, 3)
970 | INSERTED64(not_word_1_1, 4, 4)
971 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
973 else if (EXTRACTED32(WORD, 1, 8) == 0
974 && EXTRACTED32(WORD, 9, 31) != 0) {
975 /* denormalized operand */
976 int sign = EXTRACTED32(WORD, 0, 0);
978 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
979 /* normalize the operand */
980 while (MASKED64(frac, 0, 0) == 0) {
984 FRT = (INSERTED64(sign, 0, 0)
985 | INSERTED64(exp + 1023, 1, 11)
986 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
988 else if (EXTRACTED32(WORD, 1, 8) == 255
989 || EXTRACTED32(WORD, 1, 31) == 0) {
990 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
991 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
992 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
993 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
994 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
997 error("DOUBLE - unknown case\n");
1002 # Convert 64bit single to 32bit double
1003 unsigned32::function::SINGLE:unsigned64 FRS
1005 if (EXTRACTED64(FRS, 1, 11) > 896
1006 || EXTRACTED64(FRS, 1, 63) == 0) {
1007 /* no denormalization required (includes Zero/Infinity/NaN) */
1008 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
1009 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
1011 else if (874 <= EXTRACTED64(FRS, 1, 11)
1012 && EXTRACTED64(FRS, 1, 11) <= 896) {
1013 /* denormalization required */
1014 int sign = EXTRACTED64(FRS, 0, 0);
1015 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
1016 unsigned64 frac = (BIT64(0)
1017 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
1018 /* denormalize the operand */
1019 while (exp < -126) {
1020 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1023 WORD = (INSERTED32(sign, 0, 0)
1024 | INSERTED32(0x00, 1, 8)
1025 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
1028 WORD = 0x0; /* ??? */
1033 # round 64bit double to 64bit but single
1034 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
1035 /* comparisons ignore u bits */
1038 int lsb = EXTRACTED64(*frac_grx, 23, 23);
1039 int gbit = EXTRACTED64(*frac_grx, 24, 24);
1040 int rbit = EXTRACTED64(*frac_grx, 25, 25);
1041 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
1042 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
1043 if (lsb == 1 && gbit == 1) inc = 1;
1044 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1045 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1047 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
1048 if (sign == 0 && gbit == 1) inc = 1;
1049 if (sign == 0 && rbit == 1) inc = 1;
1050 if (sign == 0 && xbit == 1) inc = 1;
1052 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
1053 if (sign == 1 && gbit == 1) inc = 1;
1054 if (sign == 1 && rbit == 1) inc = 1;
1055 if (sign == 1 && xbit == 1) inc = 1;
1057 /* work out addition in low 25 bits of out */
1058 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
1059 *frac_grx = INSERTED64(out, 0, 23);
1060 if (out & BIT64(64 - 23 - 1 - 1)) {
1061 *frac_grx = (BIT64(0) |
1062 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
1065 /* frac_grx[24:52] = 0 already */
1067 FPSCR_SET_FI(gbit || rbit || xbit);
1071 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
1073 if (round_mode == fpscr_rn_round_to_nearest) {
1074 if (*frac64 == 1 && gbit == 1) inc = 1;
1075 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
1076 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
1078 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1079 if (sign == 0 && gbit == 1) inc = 1;
1080 if (sign == 0 && rbit == 1) inc = 1;
1081 if (sign == 0 && xbit == 1) inc = 1;
1083 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1084 if (sign == 1 && gbit == 1) inc = 1;
1085 if (sign == 1 && rbit == 1) inc = 1;
1086 if (sign == 1 && xbit == 1) inc = 1;
1088 /* frac[0:64] = frac[0:64} + inc */
1089 *frac += (*frac64 && inc ? 1 : 0);
1090 *frac64 = (*frac64 + inc) & 0x1;
1092 FPSCR_SET_FI(gbit | rbit | xbit);
1095 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
1098 int lsb = EXTRACTED64(*frac, 52, 52);
1099 int gbit = EXTRACTED64(*frac, 53, 53);
1100 int rbit = EXTRACTED64(*frac, 54, 54);
1101 int xbit = EXTRACTED64(*frac, 55, 55);
1102 if (round_mode == fpscr_rn_round_to_nearest) {
1103 if (lsb == 1 && gbit == 1) inc = 1;
1104 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1105 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1107 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1108 if (sign == 0 && gbit == 1) inc = 1;
1109 if (sign == 0 && rbit == 1) inc = 1;
1110 if (sign == 0 && xbit == 1) inc = 1;
1112 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1113 if (sign == 1 && gbit == 1) inc = 1;
1114 if (sign == 1 && rbit == 1) inc = 1;
1115 if (sign == 1 && xbit == 1) inc = 1;
1117 /* frac//carry_out = frac + inc */
1118 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1119 carry_out = EXTRACTED64(*frac, 0, 0);
1121 if (carry_out == 1) *exp = *exp + 1;
1123 FPSCR_SET_FI(gbit | rbit | xbit);
1124 FPSCR_SET_XX(FPSCR & fpscr_fi);
1127 # conversion of FP to integer
1128 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
1131 unsigned64 frac = 0;
1136 int sign = EXTRACTED64(frb, 0, 0);
1137 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1138 goto Infinity_Operand;
1139 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1141 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1143 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
1144 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1145 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1146 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1147 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1150 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1151 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1154 gbit = 0, rbit = 0, xbit = 0;
1155 for (i = 1; i <= 63 - exp; i++) {
1159 frac64 = EXTRACTED64(frac, 63, 63);
1160 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1162 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1163 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1166 frac += (frac64 ? 1 : 0);
1167 frac64 = (frac64 + 1) & 0x1;
1169 if (tgt_precision == 32 /* can ignore frac64 in compare */
1170 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1172 if (tgt_precision == 64 /* can ignore frac64 in compare */
1173 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1175 if (tgt_precision == 32 /* can ignore frac64 in compare */
1176 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1178 if (tgt_precision == 64 /* can ignore frac64 in compare */
1179 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1181 FPSCR_SET_XX(FPSCR & fpscr_fi);
1182 if (tgt_precision == 32)
1183 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1184 if (tgt_precision == 64)
1185 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1186 /*FPSCR[fprf] = undefined */
1192 FPSCR_OR_VX(fpscr_vxcvi);
1193 if ((FPSCR & fpscr_ve) == 0) {
1194 if (tgt_precision == 32) {
1195 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1196 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1199 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1200 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1202 /* FPSCR[FPRF] = undefined */
1209 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1210 if ((FPSCR & fpscr_ve) == 0) {
1211 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1212 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1213 /* FPSCR[fprf] = undefined */
1220 FPSCR_OR_VX(fpscr_vxcvi);
1221 if ((FPSCR & fpscr_ve) == 0) {
1222 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1223 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1224 /* FPSCR[fprf] = undefined */
1231 FPSCR_OR_VX(fpscr_vxcvi);
1232 if ((FPSCR & fpscr_ve) == 0) {
1233 if (tgt_precision == 32) {
1234 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1235 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1238 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1239 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1241 /* FPSCR[fprf] = undefined */
1247 # extract out raw fields of a FP number
1248 int::function::sign:unsigned64 FRS
1249 return (MASKED64(FRS, 0, 0)
1252 int::function::biased_exp:unsigned64 frs, int single
1254 return EXTRACTED64(frs, 1, 8);
1256 return EXTRACTED64(frs, 1, 11);
1257 unsigned64::function::fraction:unsigned64 frs, int single
1259 return EXTRACTED64(frs, 9, 31);
1261 return EXTRACTED64(frs, 12, 63);
1263 # a number?, each of the below return +1 or -1 (based on sign bit)
1265 int::function::is_nor:unsigned64 frs, int single
1266 int exp = biased_exp(frs, single);
1268 && exp <= (single ? 254 : 2046));
1269 int::function::is_zero:unsigned64 FRS
1270 return (MASKED64(FRS, 1, 63) == 0
1273 int::function::is_den:unsigned64 frs, int single
1274 int exp = biased_exp(frs, single);
1275 unsigned64 frac = fraction(frs, single);
1276 return (exp == 0 && frac != 0
1279 int::function::is_inf:unsigned64 frs, int single
1280 int exp = biased_exp(frs, single);
1281 int frac = fraction(frs, single);
1282 return (exp == (single ? 255 : 2047) && frac == 0
1285 int::function::is_NaN:unsigned64 frs, int single
1286 int exp = biased_exp(frs, single);
1287 int frac = fraction(frs, single);
1288 return (exp == (single ? 255 : 2047) && frac != 0
1291 int::function::is_SNaN:unsigned64 frs, int single
1292 return (is_NaN(frs, single)
1293 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1296 int::function::is_QNaN:unsigned64 frs, int single
1297 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1298 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1299 return *(double*)fra < *(double*)frb;
1300 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1301 return *(double*)fra > *(double*)frb;
1302 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1303 return *(double*)fra == *(double*)frb;
1306 # which quiet nan should become the result
1307 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1309 if (is_NaN(fra, single))
1311 else if (is_NaN(frb, single))
1312 if (instruction_is_frsp)
1313 frt = MASKED64(frb, 0, 34);
1316 else if (is_NaN(frc, single))
1318 else if (generate_qnan)
1319 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1321 error("select_qnan - default reached\n");
1325 # detect invalid operation
1326 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1328 if ((check & fpscr_vxsnan)
1329 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1330 FPSCR_OR_VX(fpscr_vxsnan);
1333 if ((check & fpscr_vxisi)
1334 && (is_inf(fra, single) && is_inf(frb, single))
1335 && ((negate && sign(fra) != sign(frb))
1336 || (!negate && sign(fra) == sign(frb)))) {
1337 /*FIXME: don't handle inf-inf VS inf+-inf */
1338 FPSCR_OR_VX(fpscr_vxisi);
1341 if ((check & fpscr_vxidi)
1342 && (is_inf(fra, single) && is_inf(frb, single))) {
1343 FPSCR_OR_VX(fpscr_vxidi);
1346 if ((check & fpscr_vxzdz)
1347 && (is_zero(fra) && is_zero(frb))) {
1348 FPSCR_OR_VX(fpscr_vxzdz);
1351 if ((check & fpscr_vximz)
1352 && (is_zero(fra) && is_inf(frb, single))) {
1353 FPSCR_OR_VX(fpscr_vximz);
1356 if ((check & fpscr_vxvc)
1357 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1358 FPSCR_OR_VX(fpscr_vxvc);
1361 if ((check & fpscr_vxsoft)) {
1362 FPSCR_OR_VX(fpscr_vxsoft);
1365 if ((check & fpscr_vxsqrt)
1367 FPSCR_OR_VX(fpscr_vxsqrt);
1370 /* if ((check && fpscr_vxcvi) {
1371 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1372 FPSCR_OR_VX(fpscr_vxcvi);
1382 # handle case of invalid operation
1383 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
1384 if (FPSCR & fpscr_ve) {
1385 /* invalid operation exception enabled */
1389 /* fpscr_FPRF unchanged */
1392 /* invalid operation exception disabled */
1393 if (instruction_is_convert_to_64bit) {
1396 else if (instruction_is_convert_to_32bit) {
1399 else { /* arrith, frsp */
1400 *frt = select_qnan(fra, frb, frc,
1401 instruction_is_frsp, 0/*generate*/, single);
1404 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1412 # I.2.4.1 Branch Instructions
1414 0.18,6.LI,30.AA,31.LK:I:t::Branch
1415 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1416 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1417 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1418 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1419 if (AA) NIA = IEA(EXTS(LI_0b00));
1420 else NIA = IEA(CIA + EXTS(LI_0b00));
1421 if (LK) LR = (spreg)CIA+4;
1422 if (CURRENT_MODEL_ISSUE > 0)
1423 model_branches(cpu_model(processor), 1, -1);
1425 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
1426 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1427 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1428 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1429 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1430 int M, ctr_ok, cond_ok, succeed;
1431 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1432 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1433 if (is_64bit_implementation && is_64bit_mode) M = 0;
1435 if (!BO{2}) CTR = CTR - 1;
1436 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1437 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1438 if (ctr_ok && cond_ok) {
1439 if (AA) NIA = IEA(EXTS(BD_0b00));
1440 else NIA = IEA(CIA + EXTS(BD_0b00));
1445 if (LK) LR = (spreg)IEA(CIA + 4);
1446 if (CURRENT_MODEL_ISSUE > 0)
1447 model_branches(cpu_model(processor), succeed, BO);
1450 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1451 reverse = EXTS(BD_0b00) < 0;
1452 } else { /* branch prediction bit not set */
1453 reverse = EXTS(BD_0b00) >= 0;
1455 if (CURRENT_MODEL_ISSUE > 0)
1456 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1459 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
1460 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1461 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1462 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1463 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1464 int M, ctr_ok, cond_ok, succeed;
1465 if (is_64bit_implementation && is_64bit_mode) M = 0;
1467 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1468 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1469 if (!BO{2}) CTR = CTR - 1;
1470 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1471 cond_ok = BO{0} || (CR{BI} == BO{1});
1472 if (ctr_ok && cond_ok) {
1478 if (LK) LR = (spreg)IEA(CIA + 4);
1479 if (CURRENT_MODEL_ISSUE > 0) {
1480 model_branches(cpu_model(processor), succeed, BO);
1482 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1485 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
1486 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1487 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1488 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1489 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1490 int cond_ok, succeed;
1491 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1492 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1493 cond_ok = BO{0} || (CR{BI} == BO{1});
1495 NIA = IEA(CTR_0b00);
1500 if (LK) LR = (spreg)IEA(CIA + 4);
1501 if (CURRENT_MODEL_ISSUE > 0) {
1502 model_branches(cpu_model(processor), succeed, BO);
1504 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1508 # I.2.4.2 System Call Instruction
1510 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
1511 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1512 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1513 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1514 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1515 if (CURRENT_MODEL_ISSUE > 0)
1516 model_serialize(my_index, cpu_model(processor));
1517 system_call_interrupt(processor, cia);
1520 # I.2.4.3 Condition Register Logical Instructions
1522 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1523 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1524 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1525 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1526 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1527 BLIT32(CR, BT, CR{BA} && CR{BB});
1528 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1530 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1531 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1532 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1533 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1534 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1535 BLIT32(CR, BT, CR{BA} || CR{BB});
1536 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1538 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1539 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1540 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1541 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1542 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1543 BLIT32(CR, BT, CR{BA} != CR{BB});
1544 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1546 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1547 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1548 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1549 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1550 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1551 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1552 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1554 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1555 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1556 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1557 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1558 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1559 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1560 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1562 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1563 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1564 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1565 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1566 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1567 BLIT32(CR, BT, CR{BA} == CR{BB});
1568 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1570 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1571 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1572 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1573 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1574 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1575 BLIT32(CR, BT, CR{BA} && !CR{BB});
1576 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1578 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1579 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1580 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1581 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1582 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1583 BLIT32(CR, BT, CR{BA} || !CR{BB});
1584 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1587 # I.2.4.4 Condition Register Field Instruction
1589 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1590 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1591 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1592 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1593 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1594 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1595 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
1599 # I.3.3.2 Fixed-Point Load Instructions
1602 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1603 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1604 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1605 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1606 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1612 *rT = MEM(unsigned, EA, 1);
1613 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1616 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1617 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1618 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1619 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1620 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1626 *rT = MEM(unsigned, EA, 1);
1627 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1629 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1630 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1631 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1632 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1633 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1635 if (RA == 0 || RA == RT)
1636 program_interrupt(processor, cia,
1637 illegal_instruction_program_interrupt);
1639 *rT = MEM(unsigned, EA, 1);
1641 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1643 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1644 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1645 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1646 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1647 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1649 if (RA == 0 || RA == RT)
1650 program_interrupt(processor, cia,
1651 illegal_instruction_program_interrupt);
1653 *rT = MEM(unsigned, EA, 1);
1655 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1657 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1658 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1659 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1660 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1661 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1667 *rT = MEM(unsigned, EA, 2);
1668 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1670 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1671 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1672 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1673 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1674 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1680 *rT = MEM(unsigned, EA, 2);
1681 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1683 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1684 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1685 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1686 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1687 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1689 if (RA == 0 || RA == RT)
1690 program_interrupt(processor, cia,
1691 illegal_instruction_program_interrupt);
1693 *rT = MEM(unsigned, EA, 2);
1695 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1697 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1698 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1699 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1700 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1701 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1703 if (RA == 0 || RA == RT)
1704 program_interrupt(processor, cia,
1705 illegal_instruction_program_interrupt);
1707 *rT = MEM(unsigned, EA, 2);
1709 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1711 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1712 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1713 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1714 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1715 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1721 *rT = MEM(signed, EA, 2);
1722 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1724 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1725 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1726 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1727 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1728 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1734 *rT = MEM(signed, EA, 2);
1735 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1737 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1738 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1739 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1740 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1741 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1743 if (RA == 0 || RA == RT)
1744 program_interrupt(processor, cia,
1745 illegal_instruction_program_interrupt);
1747 *rT = MEM(signed, EA, 2);
1748 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1750 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1751 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1752 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1753 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1754 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1756 if (RA == 0 || RA == RT)
1757 program_interrupt(processor, cia,
1758 illegal_instruction_program_interrupt);
1760 *rT = MEM(signed, EA, 2);
1762 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1764 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1765 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1766 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1767 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1768 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1774 *rT = MEM(unsigned, EA, 4);
1775 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1777 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1778 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1779 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1780 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1781 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1787 *rT = MEM(unsigned, EA, 4);
1788 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1790 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1791 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1792 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1793 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1794 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1796 if (RA == 0 || RA == RT)
1797 program_interrupt(processor, cia,
1798 illegal_instruction_program_interrupt);
1800 *rT = MEM(unsigned, EA, 4);
1802 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1804 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1805 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1806 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1807 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1808 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1810 if (RA == 0 || RA == RT)
1811 program_interrupt(processor, cia,
1812 illegal_instruction_program_interrupt);
1814 *rT = MEM(unsigned, EA, 4);
1816 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1818 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1821 # if (RA == 0) b = 0;
1823 # EA = b + EXTS(DS_0b00);
1824 # *rT = MEM(signed, EA, 4);
1826 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1829 # if (RA == 0) b = 0;
1832 # *rT = MEM(signed, EA, 4);
1834 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1836 # if (RA == 0 || RA == RT)
1837 # program_interrupt(processor, cia
1838 # illegal_instruction_program_interrupt);
1840 # *rT = MEM(signed, EA, 4);
1843 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1846 # if (RA == 0) b = 0;
1848 # EA = b + EXTS(DS_0b00);
1849 # *rT = MEM(unsigned, EA, 8);
1851 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1854 # if (RA == 0) b = 0;
1857 # *rT = MEM(unsigned, EA, 8);
1859 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1861 # if (RA == 0 || RA == RT)
1862 # program_interrupt(processor, cia
1863 # illegal_instruction_program_interrupt);
1864 # EA = *rA + EXTS(DS_0b00);
1865 # *rT = MEM(unsigned, EA, 8);
1868 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1870 # if (RA == 0 || RA == RT)
1871 # program_interrupt(processor, cia
1872 # illegal_instruction_program_interrupt);
1874 # *rT = MEM(unsigned, EA, 8);
1880 # I.3.3.3 Fixed-Point Store Instructions
1883 0.38,6.RS,11.RA,16.D:D:::Store Byte
1884 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1885 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1886 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1887 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1894 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1896 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1897 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1898 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1899 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1900 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1907 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1909 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1910 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1911 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1912 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1913 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1916 program_interrupt(processor, cia,
1917 illegal_instruction_program_interrupt);
1921 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1923 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1924 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 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, 3, 0
1930 program_interrupt(processor, cia,
1931 illegal_instruction_program_interrupt);
1935 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1937 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1938 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1939 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1940 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1941 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1948 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1950 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1951 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1952 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1953 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1954 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1961 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1963 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1964 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1965 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1966 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1967 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1970 program_interrupt(processor, cia,
1971 illegal_instruction_program_interrupt);
1975 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1977 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1978 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1979 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1980 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1981 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1984 program_interrupt(processor, cia,
1985 illegal_instruction_program_interrupt);
1989 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1991 0.36,6.RS,11.RA,16.D:D:::Store Word
1992 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1993 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1994 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1995 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2002 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
2004 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
2005 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2006 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2007 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2008 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2015 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2017 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
2018 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2019 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2020 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2021 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2024 program_interrupt(processor, cia,
2025 illegal_instruction_program_interrupt);
2029 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2031 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
2032 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2033 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2034 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2035 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2038 program_interrupt(processor, cia,
2039 illegal_instruction_program_interrupt);
2043 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2045 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2048 # if (RA == 0) b = 0;
2050 # EA = b + EXTS(DS_0b00);
2051 # STORE(EA, 8, *rS);
2052 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2055 # if (RA == 0) b = 0;
2058 # STORE(EA, 8, *rS);
2059 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2062 # program_interrupt(processor, cia
2063 # illegal_instruction_program_interrupt);
2064 # EA = *rA + EXTS(DS_0b00);
2065 # STORE(EA, 8, *rS);
2067 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2070 # program_interrupt(processor, cia
2071 # illegal_instruction_program_interrupt);
2073 # STORE(EA, 8, *rS);
2078 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2081 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2082 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2083 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2084 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2085 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2091 *rT = SWAP_2(MEM(unsigned, EA, 2));
2092 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2094 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2095 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2096 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2097 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2098 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2104 *rT = SWAP_4(MEM(unsigned, EA, 4));
2105 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2107 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2108 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2109 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2110 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2111 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2117 STORE(EA, 2, SWAP_2(*rS));
2118 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2120 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2121 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2122 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2123 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2124 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2130 STORE(EA, 4, SWAP_4(*rS));
2131 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2135 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2138 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
2140 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2144 # I.3.3.6 Fixed-Point Move Assist Instructions
2147 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
2149 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2151 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
2153 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2157 # I.3.3.7 Storage Synchronization Instructions
2159 # HACK: Rather than monitor addresses looking for a reason
2160 # to cancel a reservation. This code instead keeps
2161 # a copy of the data read from memory. Before performing
2162 # a store, the memory area is checked to see if it has
2164 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2165 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2166 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2167 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2168 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2175 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2176 RESERVE_DATA = MEM(unsigned, EA, 4);
2178 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2180 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2187 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2188 RESERVE_DATA = MEM(unsigned, EA, 8);
2190 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2192 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2193 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2194 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2195 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2196 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2203 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2204 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2206 CR_SET_XER_SO(0, cr_i_zero);
2209 /* ment to randomly to store, we never do! */
2210 CR_SET_XER_SO(0, 0);
2215 CR_SET_XER_SO(0, 0);
2217 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2219 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2226 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2227 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2229 CR_SET_XER_SO(0, cr_i_zero);
2232 /* ment to randomly to store, we never do */
2233 CR_SET_XER_SO(0, 0);
2238 CR_SET_XER_SO(0, 0);
2240 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2242 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2243 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2244 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2245 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2246 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2251 # I.3.3.9 Fixed-Point Arithmetic Instructions
2254 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
2255 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2256 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2257 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2258 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2259 if (RA_is_0) *rT = EXTS(SI);
2260 else *rT = *rA + EXTS(SI);
2261 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2263 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2264 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2265 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2266 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2267 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2268 if (RA_is_0) *rT = EXTS(SI) << 16;
2269 else *rT = *rA + (EXTS(SI) << 16);
2270 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2272 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2273 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2274 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2275 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2276 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2279 ALU_END(*rT, 0/*CA*/, OE, Rc);
2280 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2282 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2283 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2284 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2285 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2286 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2291 ALU_END(*rT, 0/*CA*/, OE, Rc);
2292 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2294 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2295 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2296 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2297 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2298 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2301 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2302 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2304 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2305 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2306 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2307 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2308 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2311 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2312 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
2314 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2315 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2316 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2317 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2318 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2323 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2324 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2326 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2327 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2328 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2329 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2330 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2333 ALU_END(*rT, 1/*CA*/, OE, Rc);
2334 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2336 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2337 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2338 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2339 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2340 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2341 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2346 ALU_END(*rT, 1/*CA*/, OE, Rc);
2347 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2349 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2350 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2351 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2352 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2353 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2357 ALU_END(*rT, 1/*CA*/, OE, Rc);
2358 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2360 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2361 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2362 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2363 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2364 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2369 ALU_END(*rT, 1/*CA*/, OE, Rc);
2370 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2372 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2373 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2374 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2375 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2376 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2380 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2382 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2383 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2384 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2385 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2386 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2391 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2393 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2394 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2395 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2396 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2397 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2400 ALU_END(*rT, 1/*CA*/, OE, Rc);
2401 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2403 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2404 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2405 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2406 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2407 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2411 ALU_END(*rT, 1/*CA*/, OE, Rc);
2412 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2414 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2415 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2416 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2417 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2418 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2422 ALU_END(*rT,0/*CA*/,OE,Rc);
2423 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2425 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2426 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2427 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2428 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2429 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2430 signed_word prod = *rA * EXTS(SI);
2432 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2434 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2436 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2437 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2438 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2439 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2440 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2441 signed64 a = (signed32)(*rA);
2442 signed64 b = (signed32)(*rB);
2443 signed64 prod = a * b;
2444 signed_word t = prod;
2446 if (t != prod && OE)
2447 XER |= (xer_overflow | xer_summary_overflow);
2448 CR0_COMPARE(t, 0, Rc);
2449 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2451 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2453 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2454 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2455 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2456 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2457 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2458 signed64 a = (signed32)(*rA);
2459 signed64 b = (signed32)(*rB);
2460 signed64 prod = a * b;
2461 signed_word t = EXTRACTED64(prod, 0, 31);
2463 CR0_COMPARE(t, 0, Rc);
2464 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2466 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2468 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2469 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2470 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2471 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2472 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2473 unsigned64 a = (unsigned32)(*rA);
2474 unsigned64 b = (unsigned32)(*rB);
2475 unsigned64 prod = a * b;
2476 signed_word t = EXTRACTED64(prod, 0, 31);
2478 CR0_COMPARE(t, 0, Rc);
2479 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2481 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2483 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2484 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2485 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2486 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2487 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2488 signed64 dividend = (signed32)(*rA);
2489 signed64 divisor = (signed32)(*rB);
2490 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2491 || (dividend == 0x80000000 && divisor == -1)) {
2493 XER |= (xer_overflow | xer_summary_overflow);
2494 CR0_COMPARE(0, 0, Rc);
2497 signed64 quotent = dividend / divisor;
2499 CR0_COMPARE((signed_word)quotent, 0, Rc);
2501 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2503 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2505 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2506 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2507 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2508 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2509 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2510 unsigned64 dividend = (unsigned32)(*rA);
2511 unsigned64 divisor = (unsigned32)(*rB);
2514 XER |= (xer_overflow | xer_summary_overflow);
2515 CR0_COMPARE(0, 0, Rc);
2518 unsigned64 quotent = dividend / divisor;
2520 CR0_COMPARE((signed_word)quotent, 0, Rc);
2522 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2526 # I.3.3.10 Fixed-Point Compare Instructions
2529 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2530 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2531 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2532 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2533 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2534 if (!is_64bit_mode && L)
2535 program_interrupt(processor, cia,
2536 illegal_instruction_program_interrupt);
2539 signed_word b = EXTS(SI);
2544 CR_COMPARE(BF, a, b);
2546 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2548 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2549 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2550 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2551 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2552 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2553 if (!is_64bit_mode && L)
2554 program_interrupt(processor, cia,
2555 illegal_instruction_program_interrupt);
2567 CR_COMPARE(BF, a, b);
2569 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2571 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2572 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2573 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2574 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2575 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2576 if (!is_64bit_mode && L)
2577 program_interrupt(processor, cia,
2578 illegal_instruction_program_interrupt);
2581 unsigned_word b = UI;
2583 a = MASKED(*rA, 32, 63);
2586 CR_COMPARE(BF, a, b);
2588 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2590 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2591 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2592 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2593 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2594 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2595 if (!is_64bit_mode && L)
2596 program_interrupt(processor, cia,
2597 illegal_instruction_program_interrupt);
2602 a = MASKED(*rA, 32, 63);
2603 b = MASKED(*rB, 32, 63);
2609 CR_COMPARE(BF, a, b);
2611 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2615 # I.3.3.11 Fixed-Point Trap Instructions
2618 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2620 program_interrupt(processor, cia,
2621 illegal_instruction_program_interrupt);
2623 signed_word a = *rA;
2624 signed_word b = EXTS(SI);
2625 if ((a < b && TO{0})
2627 || (a == b && TO{2})
2628 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2629 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2631 program_interrupt(processor, cia,
2632 trap_program_interrupt);
2635 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2636 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2637 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2638 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2639 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2640 signed_word a = EXTENDED(*rA);
2641 signed_word b = EXTS(SI);
2642 if ((a < b && TO{0})
2644 || (a == b && TO{2})
2645 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2646 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2648 program_interrupt(processor, cia,
2649 trap_program_interrupt);
2651 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2653 program_interrupt(processor, cia,
2654 illegal_instruction_program_interrupt);
2656 signed_word a = *rA;
2657 signed_word b = *rB;
2658 if ((a < b && TO{0})
2660 || (a == b && TO{2})
2661 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2662 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2664 program_interrupt(processor, cia,
2665 trap_program_interrupt);
2668 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2669 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2670 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2671 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2672 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2673 signed_word a = EXTENDED(*rA);
2674 signed_word b = EXTENDED(*rB);
2675 if (TO == 12 && rA == rB) {
2676 ITRACE(trace_breakpoint, ("breakpoint\n"));
2677 cpu_halt(processor, cia, was_trap, 0);
2679 else if ((a < b && TO{0})
2681 || (a == b && TO{2})
2682 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2683 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2685 program_interrupt(processor, cia,
2686 trap_program_interrupt);
2689 # I.3.3.12 Fixed-Point Logical Instructions
2692 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2693 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2694 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2695 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2696 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2698 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2699 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2701 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2702 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2703 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2704 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2705 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2706 *rA = *rS & (UI << 16);
2707 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2708 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2710 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2711 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2712 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2713 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2714 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2716 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2718 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2719 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2720 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2721 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2722 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2723 *rA = *rS | (UI << 16);
2724 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2726 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2727 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2728 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2729 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2730 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2732 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2734 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2735 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2736 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2737 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2738 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2739 *rA = *rS ^ (UI << 16);
2740 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2742 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
2743 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2744 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2745 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2746 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2748 CR0_COMPARE(*rA, 0, Rc);
2749 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2751 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
2752 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2753 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2754 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2755 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2757 CR0_COMPARE(*rA, 0, Rc);
2758 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2760 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
2761 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2762 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2763 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2764 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2766 CR0_COMPARE(*rA, 0, Rc);
2767 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2769 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
2770 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2771 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2772 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2773 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2775 CR0_COMPARE(*rA, 0, Rc);
2776 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2778 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
2779 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2780 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2781 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2782 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2784 CR0_COMPARE(*rA, 0, Rc);
2785 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2787 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
2788 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2789 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2790 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2791 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2792 # *rA = ~(*rS ^ *rB); /* A === B */
2793 # CR0_COMPARE(*rA, 0, Rc);
2795 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
2796 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2797 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2798 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2799 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2801 CR0_COMPARE(*rA, 0, Rc);
2802 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2804 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
2805 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2806 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2807 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2808 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2810 CR0_COMPARE(*rA, 0, Rc);
2811 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2813 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
2814 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2815 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2816 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2817 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2818 *rA = (signed_word)(signed8)*rS;
2819 CR0_COMPARE(*rA, 0, Rc);
2820 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2822 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
2823 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2824 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2825 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2826 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2827 *rA = (signed_word)(signed16)*rS;
2828 CR0_COMPARE(*rA, 0, Rc);
2829 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2831 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2832 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2833 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2834 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2835 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2836 # *rA = (signed_word)(signed32)*rS;
2837 # CR0_COMPARE(*rA, 0, Rc);
2839 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2841 # unsigned64 mask = BIT64(0);
2842 # unsigned64 source = *rS;
2843 # while (!(source & mask) && mask != 0) {
2848 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2850 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
2851 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2852 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2853 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2854 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2856 unsigned32 mask = BIT32(0);
2857 unsigned32 source = *rS;
2858 while (!(source & mask) && mask != 0) {
2863 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2867 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2870 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
2871 # long n = (sh_5 << 4) | sh_0_4;
2872 # unsigned_word r = ROTL64(*rS, n);
2873 # long b = (mb_5 << 4) | mb_0_4;
2874 # unsigned_word m = MASK(b, 63);
2875 # signed_word result = r & m;
2877 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2879 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
2880 # long n = (sh_5 << 4) | sh_0_4;
2881 # unsigned_word r = ROTL64(*rS, n);
2882 # long e = (me_5 << 4) | me_0_4;
2883 # unsigned_word m = MASK(0, e);
2884 # signed_word result = r & m;
2886 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2888 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
2889 # long n = (sh_5 << 4) | sh_0_4;
2890 # unsigned_word r = ROTL64(*rS, n);
2891 # long b = (mb_5 << 4) | mb_0_4;
2892 # unsigned_word m = MASK(0, (64-n));
2893 # signed_word result = r & m;
2895 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2897 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2898 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2899 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2900 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2901 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2904 unsigned32 r = ROTL32(s, n);
2905 unsigned32 m = MASK(MB+32, ME+32);
2906 signed_word result = r & m;
2908 CR0_COMPARE(result, 0, Rc);
2910 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
2911 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
2912 (unsigned long)result, (unsigned long)CR));
2913 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2915 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2916 # long n = MASKED(*rB, 58, 63);
2917 # unsigned_word r = ROTL64(*rS, n);
2918 # long b = (mb_5 << 4) | mb_0_4;
2919 # unsigned_word m = MASK(b, 63);
2920 # signed_word result = r & m;
2922 # CR0_COMPARE(result, 0, Rc);
2924 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2925 # long n = MASKED(*rB, 58, 63);
2926 # unsigned_word r = ROTL64(*rS, n);
2927 # long e = (me_5 << 4) | me_0_4;
2928 # unsigned_word m = MASK(0, e);
2929 # signed_word result = r & m;
2931 # CR0_COMPARE(result, 0, Rc);
2933 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2934 # long n = MASKED(*rB, 59, 63);
2935 # unsigned32 r = ROTL32(*rS, n);
2936 # unsigned32 m = MASK(MB+32, ME+32);
2937 # signed_word result = r & m;
2939 # CR0_COMPARE(result, 0, Rc);
2941 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
2942 # long n = (sh_5 << 4) | sh_0_4;
2943 # unsigned_word r = ROTL64(*rS, n);
2944 # long b = (mb_5 << 4) | mb_0_4;
2945 # unsigned_word m = MASK(b, (64-n));
2946 # signed_word result = (r & m) | (*rA & ~m)
2948 # CR0_COMPARE(result, 0, Rc);
2950 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2951 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2952 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2953 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2954 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2956 unsigned32 r = ROTL32(*rS, n);
2957 unsigned32 m = MASK(MB+32, ME+32);
2958 signed_word result = (r & m) | (*rA & ~m);
2960 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
2961 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
2962 (unsigned long)result));
2963 CR0_COMPARE(result, 0, Rc);
2964 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2967 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2969 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2970 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2971 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2972 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2973 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2974 int n = MASKED(*rB, 59, 63);
2975 unsigned32 source = *rS;
2976 signed_word shifted;
2978 shifted = (source << n);
2982 CR0_COMPARE(shifted, 0, Rc);
2984 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2985 n, (unsigned long)source, (unsigned long)shifted));
2986 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2988 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
2990 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
2991 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2992 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2993 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2994 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2995 int n = MASKED(*rB, 59, 63);
2996 unsigned32 source = *rS;
2997 signed_word shifted;
2999 shifted = (source >> n);
3003 CR0_COMPARE(shifted, 0, Rc);
3005 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3006 n, (unsigned long)source, (unsigned long)shifted));
3007 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3009 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3011 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3012 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3013 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3014 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3015 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3017 signed_word r = ROTL32(*rS, /*64*/32-n);
3018 signed_word m = MASK(n+32, 63);
3019 int S = MASKED(*rS, 32, 32);
3020 signed_word shifted = (r & m) | (S ? ~m : 0);
3022 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3026 CR0_COMPARE(shifted, 0, Rc);
3027 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3029 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3031 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3032 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3033 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3034 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3035 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3036 int n = MASKED(*rB, 58, 63);
3037 int shift = (n >= 31 ? 31 : n);
3038 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3039 signed32 shifted = source >> shift;
3040 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
3041 *rA = (signed_word)shifted; /* if 64bit will sign extend */
3042 if (source < 0 && (source & mask))
3046 CR0_COMPARE(shifted, 0, Rc);
3047 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3050 # I.3.3.14 Move to/from System Register Instructions
3053 0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3054 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3055 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3056 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3057 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3058 int n = (SPR{5:9} << 5) | SPR{0:4};
3059 if (SPR{0} && IS_PROBLEM_STATE(processor))
3060 program_interrupt(processor, cia,
3061 privileged_instruction_program_interrupt);
3062 else if (!spr_is_valid(n)
3063 || spr_is_readonly(n))
3064 program_interrupt(processor, cia,
3065 illegal_instruction_program_interrupt);
3067 spreg new_val = (spr_length(n) == 64
3069 : MASKED(*rS, 32, 63));
3070 /* HACK - time base registers need to be updated immediatly */
3071 if (WITH_TIME_BASE) {
3074 cpu_set_time_base(processor,
3075 (MASKED64(cpu_get_time_base(processor), 32, 63)
3076 | INSERTED64(new_val, 0, 31)));
3079 cpu_set_time_base(processor,
3080 (MASKED64(cpu_get_time_base(processor), 0, 31)
3081 | INSERTED64(new_val, 32, 63)));
3084 cpu_set_decrementer(processor, new_val);
3095 PPC_INSN_TO_SPR(RS_BITMASK, n);
3097 0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3098 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3099 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3100 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3101 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3102 int n = (SPR{5:9} << 5) | SPR{0:4};
3103 if (SPR{0} && IS_PROBLEM_STATE(processor))
3104 program_interrupt(processor, cia,
3105 privileged_instruction_program_interrupt);
3106 else if (!spr_is_valid(n))
3107 program_interrupt(processor, cia,
3108 illegal_instruction_program_interrupt);
3110 /* HACK - some SPR's need to get their value extracted specially */
3113 PPC_INSN_FROM_SPR(RT_BITMASK, n);
3115 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3116 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3117 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3118 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3119 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3124 unsigned_word mask = 0;
3126 for (f = 0; f < 8; f++) {
3127 if (FXM & (0x80 >> f))
3128 mask |= (0xf << 4*(7-f));
3130 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3132 PPC_INSN_MTCR(RS_BITMASK, FXM);
3134 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3136 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3137 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3138 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3139 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3140 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3141 *rT = (unsigned32)CR;
3142 PPC_INSN_MFCR(RT_BITMASK);
3145 # I.4.6.2 Floating-Point Load Instructions
3148 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3149 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3150 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3151 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3152 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3158 *frT = DOUBLE(MEM(unsigned, EA, 4));
3159 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3161 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3162 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3163 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3164 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3165 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3171 *frT = DOUBLE(MEM(unsigned, EA, 4));
3172 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3174 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3175 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3176 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3177 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3178 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3181 program_interrupt(processor, cia,
3182 illegal_instruction_program_interrupt);
3184 *frT = DOUBLE(MEM(unsigned, EA, 4));
3186 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3188 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3189 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3190 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3191 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3192 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3195 program_interrupt(processor, cia,
3196 illegal_instruction_program_interrupt);
3198 *frT = DOUBLE(MEM(unsigned, EA, 4));
3200 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3202 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3203 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3204 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3205 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3206 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3212 *frT = MEM(unsigned, EA, 8);
3213 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3215 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3216 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3217 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3218 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3219 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3225 *frT = MEM(unsigned, EA, 8);
3226 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3228 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3229 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3230 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3231 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3232 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3235 program_interrupt(processor, cia,
3236 illegal_instruction_program_interrupt);
3238 *frT = MEM(unsigned, EA, 8);
3240 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3242 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3243 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3244 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3245 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3246 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3249 program_interrupt(processor, cia,
3250 illegal_instruction_program_interrupt);
3252 *frT = MEM(unsigned, EA, 8);
3254 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3258 # I.4.6.3 Floating-Point Store Instructions
3261 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3262 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3263 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3264 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3265 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3271 STORE(EA, 4, SINGLE(*frS));
3272 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3274 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3275 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3276 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3277 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3278 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3284 STORE(EA, 4, SINGLE(*frS));
3285 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3287 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3288 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3289 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3290 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3291 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3294 program_interrupt(processor, cia,
3295 illegal_instruction_program_interrupt);
3297 STORE(EA, 4, SINGLE(*frS));
3299 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3301 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3302 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3303 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3304 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3305 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3308 program_interrupt(processor, cia,
3309 illegal_instruction_program_interrupt);
3311 STORE(EA, 4, SINGLE(*frS));
3313 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3315 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3316 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3317 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3318 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3319 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3326 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3328 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3329 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3330 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3331 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3332 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3339 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3341 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3342 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3343 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3344 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3345 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3348 program_interrupt(processor, cia,
3349 illegal_instruction_program_interrupt);
3353 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3355 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3356 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3357 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3358 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3359 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3362 program_interrupt(processor, cia,
3363 illegal_instruction_program_interrupt);
3367 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3371 # I.4.6.4 Floating-Point Move Instructions
3374 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3375 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3376 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3377 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3378 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3381 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3383 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3384 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3385 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3386 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3387 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3388 *frT = *frB ^ BIT64(0);
3390 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3392 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3393 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3394 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3395 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3396 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3397 *frT = *frB & ~BIT64(0);
3399 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3401 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3402 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3403 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3404 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3405 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3406 *frT = *frB | BIT64(0);
3408 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3412 # I.4.6.5 Floating-Point Arithmetic Instructions
3415 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3416 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3417 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3418 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3419 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3421 if (is_invalid_operation(processor, cia,
3423 fpscr_vxsnan | fpscr_vxisi,
3426 invalid_arithemetic_operation(processor, cia,
3428 0, /*instruction_is_frsp*/
3429 0, /*instruction_is_convert_to_64bit*/
3430 0, /*instruction_is_convert_to_32bit*/
3431 0); /*single-precision*/
3435 double s = *(double*)frA + *(double*)frB;
3439 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3441 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3442 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3443 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3444 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3445 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3447 if (is_invalid_operation(processor, cia,
3449 fpscr_vxsnan | fpscr_vxisi,
3452 invalid_arithemetic_operation(processor, cia,
3454 0, /*instruction_is_frsp*/
3455 0, /*instruction_is_convert_to_64bit*/
3456 0, /*instruction_is_convert_to_32bit*/
3457 1); /*single-precision*/
3461 float s = *(double*)frA + *(double*)frB;
3465 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3467 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3468 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3469 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3470 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3471 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3473 if (is_invalid_operation(processor, cia,
3475 fpscr_vxsnan | fpscr_vxisi,
3478 invalid_arithemetic_operation(processor, cia,
3480 0, /*instruction_is_frsp*/
3481 0, /*instruction_is_convert_to_64bit*/
3482 0, /*instruction_is_convert_to_32bit*/
3483 0); /*single-precision*/
3487 double s = *(double*)frA - *(double*)frB;
3491 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3493 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3494 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3495 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3496 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3497 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3499 if (is_invalid_operation(processor, cia,
3501 fpscr_vxsnan | fpscr_vxisi,
3504 invalid_arithemetic_operation(processor, cia,
3506 0, /*instruction_is_frsp*/
3507 0, /*instruction_is_convert_to_64bit*/
3508 0, /*instruction_is_convert_to_32bit*/
3509 1); /*single-precision*/
3513 float s = *(double*)frA - *(double*)frB;
3517 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3519 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3520 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3521 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3522 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3523 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3525 if (is_invalid_operation(processor, cia,
3527 fpscr_vxsnan | fpscr_vximz,
3530 invalid_arithemetic_operation(processor, cia,
3532 0, /*instruction_is_frsp*/
3533 0, /*instruction_is_convert_to_64bit*/
3534 0, /*instruction_is_convert_to_32bit*/
3535 0); /*single-precision*/
3539 double s = *(double*)frA * *(double*)frC;
3543 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3545 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3546 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3547 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3548 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3549 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3551 if (is_invalid_operation(processor, cia,
3553 fpscr_vxsnan | fpscr_vximz,
3556 invalid_arithemetic_operation(processor, cia,
3558 0, /*instruction_is_frsp*/
3559 0, /*instruction_is_convert_to_64bit*/
3560 0, /*instruction_is_convert_to_32bit*/
3561 1); /*single-precision*/
3565 float s = *(double*)frA * *(double*)frC;
3569 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3571 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3572 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3573 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3574 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3575 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3577 if (is_invalid_operation(processor, cia,
3579 fpscr_vxsnan | fpscr_vxzdz,
3582 invalid_arithemetic_operation(processor, cia,
3584 0, /*instruction_is_frsp*/
3585 0, /*instruction_is_convert_to_64bit*/
3586 0, /*instruction_is_convert_to_32bit*/
3587 0); /*single-precision*/
3591 double s = *(double*)frA / *(double*)frB;
3595 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3597 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3598 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3599 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3600 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3601 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3603 if (is_invalid_operation(processor, cia,
3605 fpscr_vxsnan | fpscr_vxzdz,
3608 invalid_arithemetic_operation(processor, cia,
3610 0, /*instruction_is_frsp*/
3611 0, /*instruction_is_convert_to_64bit*/
3612 0, /*instruction_is_convert_to_32bit*/
3613 1); /*single-precision*/
3617 float s = *(double*)frA / *(double*)frB;
3621 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3623 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3624 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3625 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3626 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3627 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3629 double product; /*HACK! - incorrectly loosing precision ... */
3630 /* compute the multiply */
3631 if (is_invalid_operation(processor, cia,
3633 fpscr_vxsnan | fpscr_vximz,
3636 invalid_arithemetic_operation(processor, cia,
3637 (unsigned64*)&product, *frA, 0, *frC,
3638 0, /*instruction_is_frsp*/
3639 0, /*instruction_is_convert_to_64bit*/
3640 0, /*instruction_is_convert_to_32bit*/
3641 0); /*single-precision*/
3645 product = *(double*)frA * *(double*)frC;
3647 /* compute the add */
3648 if (is_invalid_operation(processor, cia,
3650 fpscr_vxsnan | fpscr_vxisi,
3653 invalid_arithemetic_operation(processor, cia,
3654 frT, product, *frB, 0,
3655 0, /*instruction_is_frsp*/
3656 0, /*instruction_is_convert_to_64bit*/
3657 0, /*instruction_is_convert_to_32bit*/
3658 0); /*single-precision*/
3662 double s = product + *(double*)frB;
3666 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3668 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3669 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3670 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3671 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3672 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3674 float product; /*HACK! - incorrectly loosing precision ... */
3675 /* compute the multiply */
3676 if (is_invalid_operation(processor, cia,
3678 fpscr_vxsnan | fpscr_vximz,
3681 invalid_arithemetic_operation(processor, cia,
3682 (unsigned64*)&product, *frA, 0, *frC,
3683 0, /*instruction_is_frsp*/
3684 0, /*instruction_is_convert_to_64bit*/
3685 0, /*instruction_is_convert_to_32bit*/
3686 0); /*single-precision*/
3690 product = *(double*)frA * *(double*)frC;
3692 /* compute the add */
3693 if (is_invalid_operation(processor, cia,
3695 fpscr_vxsnan | fpscr_vxisi,
3698 invalid_arithemetic_operation(processor, cia,
3699 frT, product, *frB, 0,
3700 0, /*instruction_is_frsp*/
3701 0, /*instruction_is_convert_to_64bit*/
3702 0, /*instruction_is_convert_to_32bit*/
3703 0); /*single-precision*/
3707 float s = product + *(double*)frB;
3708 *(double*)frT = (double)s;
3711 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3713 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3714 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3715 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3716 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3717 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3719 double product; /*HACK! - incorrectly loosing precision ... */
3720 /* compute the multiply */
3721 if (is_invalid_operation(processor, cia,
3723 fpscr_vxsnan | fpscr_vximz,
3726 invalid_arithemetic_operation(processor, cia,
3727 (unsigned64*)&product, *frA, 0, *frC,
3728 0, /*instruction_is_frsp*/
3729 0, /*instruction_is_convert_to_64bit*/
3730 0, /*instruction_is_convert_to_32bit*/
3731 0); /*single-precision*/
3735 product = *(double*)frA * *(double*)frC;
3737 /* compute the subtract */
3738 if (is_invalid_operation(processor, cia,
3740 fpscr_vxsnan | fpscr_vxisi,
3743 invalid_arithemetic_operation(processor, cia,
3744 frT, product, *frB, 0,
3745 0, /*instruction_is_frsp*/
3746 0, /*instruction_is_convert_to_64bit*/
3747 0, /*instruction_is_convert_to_32bit*/
3748 0); /*single-precision*/
3752 double s = product - *(double*)frB;
3756 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3758 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
3759 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3760 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3761 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3762 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3764 float product; /*HACK! - incorrectly loosing precision ... */
3765 /* compute the multiply */
3766 if (is_invalid_operation(processor, cia,
3768 fpscr_vxsnan | fpscr_vximz,
3771 invalid_arithemetic_operation(processor, cia,
3772 (unsigned64*)&product, *frA, 0, *frC,
3773 0, /*instruction_is_frsp*/
3774 0, /*instruction_is_convert_to_64bit*/
3775 0, /*instruction_is_convert_to_32bit*/
3776 0); /*single-precision*/
3780 product = *(double*)frA * *(double*)frC;
3782 /* compute the subtract */
3783 if (is_invalid_operation(processor, cia,
3785 fpscr_vxsnan | fpscr_vxisi,
3788 invalid_arithemetic_operation(processor, cia,
3789 frT, product, *frB, 0,
3790 0, /*instruction_is_frsp*/
3791 0, /*instruction_is_convert_to_64bit*/
3792 0, /*instruction_is_convert_to_32bit*/
3793 0); /*single-precision*/
3797 float s = product - *(double*)frB;
3798 *(double*)frT = (double)s;
3801 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3803 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
3804 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3805 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3806 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3807 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3809 double product; /*HACK! - incorrectly loosing precision ... */
3810 /* compute the multiply */
3811 if (is_invalid_operation(processor, cia,
3813 fpscr_vxsnan | fpscr_vximz,
3816 invalid_arithemetic_operation(processor, cia,
3817 (unsigned64*)&product, *frA, 0, *frC,
3818 0, /*instruction_is_frsp*/
3819 0, /*instruction_is_convert_to_64bit*/
3820 0, /*instruction_is_convert_to_32bit*/
3821 0); /*single-precision*/
3825 product = *(double*)frA * *(double*)frC;
3827 /* compute the add */
3828 if (is_invalid_operation(processor, cia,
3830 fpscr_vxsnan | fpscr_vxisi,
3833 invalid_arithemetic_operation(processor, cia,
3834 frT, product, *frB, 0,
3835 0, /*instruction_is_frsp*/
3836 0, /*instruction_is_convert_to_64bit*/
3837 0, /*instruction_is_convert_to_32bit*/
3838 0); /*single-precision*/
3842 double s = -(product + *(double*)frB);
3846 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3848 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
3849 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3850 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3851 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3852 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3854 float product; /*HACK! - incorrectly loosing precision ... */
3855 /* compute the multiply */
3856 if (is_invalid_operation(processor, cia,
3858 fpscr_vxsnan | fpscr_vximz,
3861 invalid_arithemetic_operation(processor, cia,
3862 (unsigned64*)&product, *frA, 0, *frC,
3863 0, /*instruction_is_frsp*/
3864 0, /*instruction_is_convert_to_64bit*/
3865 0, /*instruction_is_convert_to_32bit*/
3866 0); /*single-precision*/
3870 product = *(double*)frA * *(double*)frC;
3872 /* compute the add */
3873 if (is_invalid_operation(processor, cia,
3875 fpscr_vxsnan | fpscr_vxisi,
3878 invalid_arithemetic_operation(processor, cia,
3879 frT, product, *frB, 0,
3880 0, /*instruction_is_frsp*/
3881 0, /*instruction_is_convert_to_64bit*/
3882 0, /*instruction_is_convert_to_32bit*/
3883 0); /*single-precision*/
3887 float s = -(product + *(double*)frB);
3888 *(double*)frT = (double)s;
3891 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3893 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
3894 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3895 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3896 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3897 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3899 double product; /*HACK! - incorrectly loosing precision ... */
3900 /* compute the multiply */
3901 if (is_invalid_operation(processor, cia,
3903 fpscr_vxsnan | fpscr_vximz,
3906 invalid_arithemetic_operation(processor, cia,
3907 (unsigned64*)&product, *frA, 0, *frC,
3908 0, /*instruction_is_frsp*/
3909 0, /*instruction_is_convert_to_64bit*/
3910 0, /*instruction_is_convert_to_32bit*/
3911 0); /*single-precision*/
3915 product = *(double*)frA * *(double*)frC;
3917 /* compute the subtract */
3918 if (is_invalid_operation(processor, cia,
3920 fpscr_vxsnan | fpscr_vxisi,
3923 invalid_arithemetic_operation(processor, cia,
3924 frT, product, *frB, 0,
3925 0, /*instruction_is_frsp*/
3926 0, /*instruction_is_convert_to_64bit*/
3927 0, /*instruction_is_convert_to_32bit*/
3928 0); /*single-precision*/
3932 double s = -(product - *(double*)frB);
3936 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3938 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
3939 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3940 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3941 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3942 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3944 float product; /*HACK! - incorrectly loosing precision ... */
3945 /* compute the multiply */
3946 if (is_invalid_operation(processor, cia,
3948 fpscr_vxsnan | fpscr_vximz,
3951 invalid_arithemetic_operation(processor, cia,
3952 (unsigned64*)&product, *frA, 0, *frC,
3953 0, /*instruction_is_frsp*/
3954 0, /*instruction_is_convert_to_64bit*/
3955 0, /*instruction_is_convert_to_32bit*/
3956 0); /*single-precision*/
3960 product = *(double*)frA * *(double*)frC;
3962 /* compute the subtract */
3963 if (is_invalid_operation(processor, cia,
3965 fpscr_vxsnan | fpscr_vxisi,
3968 invalid_arithemetic_operation(processor, cia,
3969 frT, product, *frB, 0,
3970 0, /*instruction_is_frsp*/
3971 0, /*instruction_is_convert_to_64bit*/
3972 0, /*instruction_is_convert_to_32bit*/
3973 0); /*single-precision*/
3977 float s = -(product - *(double*)frB);
3978 *(double*)frT = (double)s;
3981 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3985 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
3988 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
3989 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3990 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3991 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3992 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3995 unsigned64 frac_grx;
3996 /* split off cases for what to do */
3997 if (EXTRACTED64(*frB, 1, 11) < 897
3998 && EXTRACTED64(*frB, 1, 63) > 0) {
3999 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
4000 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
4002 if (EXTRACTED64(*frB, 1, 11) > 1150
4003 && EXTRACTED64(*frB, 1, 11) < 2047) {
4004 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4005 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
4007 if (EXTRACTED64(*frB, 1, 11) > 896
4008 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
4009 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
4010 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4011 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
4012 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
4013 if (EXTRACTED64(*frB, 12, 12) == 0
4014 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
4017 Disabled_Exponent_Underflow:
4018 sign = EXTRACTED64(*frB, 0, 0);
4019 if (EXTRACTED64(*frB, 1, 11) == 0) {
4021 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4023 if (EXTRACTED64(*frB, 1, 11) > 0) {
4024 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4025 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4027 /* G|R|X == zero from above */
4028 while (exp < -126) {
4030 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4031 | MASKED64(frac_grx, 55, 55));
4033 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4034 Round_Single(processor, sign, &exp, &frac_grx);
4035 FPSCR_SET_XX(FPSCR & fpscr_fi);
4036 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4037 *frT = INSERTED64(sign, 0, 0);
4038 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4039 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4041 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4042 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4043 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4044 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4046 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4047 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4048 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4050 /*Normalize_Operand:*/
4051 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4053 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4055 *frT = (INSERTED64(sign, 0, 0)
4056 | INSERTED64(exp + 1023, 1, 11)
4057 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4060 Enabled_Exponent_Underflow:
4062 sign = EXTRACTED64(*frB, 0, 0);
4063 if (EXTRACTED64(*frB, 1, 11) == 0) {
4065 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4067 if (EXTRACTED64(*frB, 1, 11) > 0) {
4068 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4069 frac_grx = (BIT64(0) |
4070 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4072 /*Normalize_Operand:*/
4073 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4075 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4077 Round_Single(processor, sign, &exp, &frac_grx);
4078 FPSCR_SET_XX(FPSCR & fpscr_fi);
4080 *frT = (INSERTED64(sign, 0, 0)
4081 | INSERTED64(exp + 1023, 1, 11)
4082 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4083 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4084 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4086 Disabled_Exponent_Overflow:
4088 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4089 if (EXTRACTED64(*frB, 0, 0) == 0) {
4090 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4091 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4093 if (EXTRACTED64(*frB, 0, 0) == 1) {
4094 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4095 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4098 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4099 if (EXTRACTED64(*frB, 0, 0) == 0) {
4100 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4101 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4103 if (EXTRACTED64(*frB, 0, 0) == 1) {
4104 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4105 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4108 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4109 if (EXTRACTED64(*frB, 0, 0) == 0) {
4110 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4111 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4113 if (EXTRACTED64(*frB, 0, 0) == 1) {
4114 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4115 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4118 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4119 if (EXTRACTED64(*frB, 0, 0) == 0) {
4120 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4121 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4123 if (EXTRACTED64(*frB, 0, 0) == 1) {
4124 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4125 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4128 /* FPSCR[FR] <- undefined */
4132 Enabled_Exponent_Overflow:
4133 sign = EXTRACTED64(*frB, 0, 0);
4134 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4135 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4136 Round_Single(processor, sign, &exp, &frac_grx);
4137 FPSCR_SET_XX(FPSCR & fpscr_fi);
4141 *frT = (INSERTED64(sign, 0, 0)
4142 | INSERTED64(exp + 1023, 1, 11)
4143 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4144 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4145 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4149 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4150 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4156 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4157 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4162 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4163 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4168 FPSCR_OR_VX(fpscr_vxsnan);
4169 if ((FPSCR & fpscr_ve) == 0) {
4170 *frT = (MASKED64(*frB, 0, 11)
4172 | MASKED64(*frB, 13, 34));
4173 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4179 sign = EXTRACTED64(*frB, 0, 0);
4180 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4181 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4182 Round_Single(processor, sign, &exp, &frac_grx);
4183 FPSCR_SET_XX(FPSCR & fpscr_fi);
4184 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4185 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4186 *frT = (INSERTED64(sign, 0, 0)
4187 | INSERTED64(exp + 1023, 1, 11)
4188 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4189 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4190 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4193 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4195 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4197 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4199 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4201 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4202 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4203 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4204 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4205 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4207 convert_to_integer(processor, cia,
4209 fpscr_rn_round_towards_zero, 32);
4211 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4213 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4214 int sign = EXTRACTED64(*frB, 0, 0);
4216 unsigned64 frac = *frB;
4217 if (frac == 0) goto Zero_Operand;
4218 if (sign == 1) frac = ~frac + 1;
4219 while (EXTRACTED64(frac, 0, 0) == 0) {
4220 /*??? do the loop 0 times if (FRB) = max negative integer */
4221 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4224 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4225 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4226 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4227 *frT = (INSERTED64(sign, 0, 0)
4228 | INSERTED64(exp + 1023, 1, 11)
4229 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4235 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4240 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4243 # I.4.6.7 Floating-Point Compare Instructions
4246 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4247 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4248 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4249 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4250 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4253 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4254 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4255 else if (is_less_than(frA, frB))
4256 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4257 else if (is_greater_than(frA, frB))
4258 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4260 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4262 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4263 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4264 FPSCR_OR_VX(fpscr_vxsnan);
4266 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4268 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4269 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4270 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4271 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4272 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4275 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4276 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4277 else if (is_less_than(frA, frB))
4278 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4279 else if (is_greater_than(frA, frB))
4280 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4282 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4284 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4285 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4286 FPSCR_OR_VX(fpscr_vxsnan);
4287 if ((FPSCR & fpscr_ve) == 0)
4288 FPSCR_OR_VX(fpscr_vxvc);
4290 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4291 FPSCR_OR_VX(fpscr_vxvc);
4294 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4298 # I.4.6.8 Floating-Point Status and Control Register Instructions
4301 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4303 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4305 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4307 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4309 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4311 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4315 # I.A.1.1 Floating-Point Store Instruction
4317 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4320 # I.A.1.2 Floating-Point Arithmetic Instructions
4323 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
4325 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4327 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
4329 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4332 # I.A.1.3 Floating-Point Select Instruction
4335 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4339 # II.3.2 Cache Management Instructions
4342 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4343 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4344 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4345 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4346 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4347 /* blindly flush all instruction cache entries */
4348 #if WITH_IDECODE_CACHE_SIZE
4349 cpu_flush_icache(processor);
4351 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4353 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4354 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4355 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4356 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4357 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4358 cpu_synchronize_context(processor);
4359 PPC_INSN_INT(0, 0, 0);
4363 # II.3.2.2 Data Cache Instructions
4366 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4367 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4368 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4369 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4370 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4371 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4372 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4374 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4375 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4376 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4377 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4378 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4379 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4380 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4382 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4383 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4384 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4385 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4386 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4387 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4388 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4390 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4391 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4392 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4393 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4394 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4395 TRACE(trace_tbd,("Data Cache Block Store\n"));
4396 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4398 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4399 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4400 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4401 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4402 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4403 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4404 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4407 # II.3.3 Enforce In-order Execution of I/O Instruction
4410 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4411 /* Since this model has no instruction overlap
4412 this instruction need do nothing */
4415 # II.4.1 Time Base Instructions
4418 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4419 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4420 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4421 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4422 int n = (tbr{5:9} << 5) | tbr{0:4};
4424 if (is_64bit_implementation) *rT = TB;
4425 else *rT = EXTRACTED64(TB, 32, 63);
4427 else if (n == 269) {
4428 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4429 else *rT = EXTRACTED64(TB, 0, 31);
4432 program_interrupt(processor, cia,
4433 illegal_instruction_program_interrupt);
4437 # III.2.3.1 System Linkage Instructions
4440 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4441 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4442 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4443 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4444 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4445 if (IS_PROBLEM_STATE(processor)) {
4446 program_interrupt(processor, cia,
4447 privileged_instruction_program_interrupt);
4450 MSR = (MASKED(SRR1, 0, 32)
4451 | MASKED(SRR1, 37, 41)
4452 | MASKED(SRR1, 48, 63));
4453 NIA = MASKED(SRR0, 0, 61);
4454 cpu_synchronize_context(processor);
4458 # III.3.4.1 Move to/from System Register Instructions
4461 #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4462 #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4463 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4464 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4465 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4466 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4467 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4468 if (IS_PROBLEM_STATE(processor))
4469 program_interrupt(processor, cia,
4470 privileged_instruction_program_interrupt);
4474 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4475 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4476 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4477 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4478 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4479 if (IS_PROBLEM_STATE(processor))
4480 program_interrupt(processor, cia,
4481 privileged_instruction_program_interrupt);
4487 # III.4.11.1 Cache Management Instructions
4490 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4491 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4492 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4493 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4494 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4495 if (IS_PROBLEM_STATE(processor))
4496 program_interrupt(processor, cia,
4497 privileged_instruction_program_interrupt);
4499 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4502 # III.4.11.2 Segment Register Manipulation Instructions
4505 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4506 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4507 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4508 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4509 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4510 if (IS_PROBLEM_STATE(processor))
4511 program_interrupt(processor, cia,
4512 privileged_instruction_program_interrupt);
4516 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4517 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4518 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4519 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4520 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4521 if (IS_PROBLEM_STATE(processor))
4522 program_interrupt(processor, cia,
4523 privileged_instruction_program_interrupt);
4525 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4527 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4528 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4529 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4530 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4531 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4532 if (IS_PROBLEM_STATE(processor))
4533 program_interrupt(processor, cia,
4534 privileged_instruction_program_interrupt);
4538 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4539 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4540 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4541 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4542 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4543 if (IS_PROBLEM_STATE(processor))
4544 program_interrupt(processor, cia,
4545 privileged_instruction_program_interrupt);
4547 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4551 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4554 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4556 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4558 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4560 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4562 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4566 # III.A.1.2 External Access Instructions
4569 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4571 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed