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 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 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 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 # 0.0.0.0 Illegal instruction used for kernel mode emulation
1414 0.0,6./,11./,16./,21./,31.1:X:::instruction_call
1415 if (!os_emul_instruction_call(processor, cia, real_addr(cia, 1)))
1416 program_interrupt(processor, cia,
1417 illegal_instruction_program_interrupt);
1420 # I.2.4.1 Branch Instructions
1422 0.18,6.LI,30.AA,31.LK:I:t::Branch
1423 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1424 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1425 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1426 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1427 if (AA) NIA = IEA(EXTS(LI_0b00));
1428 else NIA = IEA(CIA + EXTS(LI_0b00));
1429 if (LK) LR = (spreg)CIA+4;
1430 if (CURRENT_MODEL_ISSUE > 0)
1431 model_branches(cpu_model(processor), 1, -1);
1433 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
1434 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1435 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1436 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1437 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1438 int M, ctr_ok, cond_ok, succeed;
1439 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1440 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1441 if (is_64bit_implementation && is_64bit_mode) M = 0;
1443 if (!BO{2}) CTR = CTR - 1;
1444 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1445 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1446 if (ctr_ok && cond_ok) {
1447 if (AA) NIA = IEA(EXTS(BD_0b00));
1448 else NIA = IEA(CIA + EXTS(BD_0b00));
1453 if (LK) LR = (spreg)IEA(CIA + 4);
1454 if (CURRENT_MODEL_ISSUE > 0)
1455 model_branches(cpu_model(processor), succeed, BO);
1458 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1459 reverse = EXTS(BD_0b00) < 0;
1460 } else { /* branch prediction bit not set */
1461 reverse = EXTS(BD_0b00) >= 0;
1463 if (CURRENT_MODEL_ISSUE > 0)
1464 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1467 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
1468 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1469 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1470 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1471 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1472 int M, ctr_ok, cond_ok, succeed;
1473 if (is_64bit_implementation && is_64bit_mode) M = 0;
1475 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1476 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1477 if (!BO{2}) CTR = CTR - 1;
1478 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1479 cond_ok = BO{0} || (CR{BI} == BO{1});
1480 if (ctr_ok && cond_ok) {
1486 if (LK) LR = (spreg)IEA(CIA + 4);
1487 if (CURRENT_MODEL_ISSUE > 0) {
1488 model_branches(cpu_model(processor), succeed, BO);
1490 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1493 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
1494 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1495 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1496 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1497 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1498 int cond_ok, succeed;
1499 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1500 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1501 cond_ok = BO{0} || (CR{BI} == BO{1});
1503 NIA = IEA(CTR_0b00);
1508 if (LK) LR = (spreg)IEA(CIA + 4);
1509 if (CURRENT_MODEL_ISSUE > 0) {
1510 model_branches(cpu_model(processor), succeed, BO);
1512 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1516 # I.2.4.2 System Call Instruction
1518 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
1519 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1520 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1521 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1522 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1523 if (CURRENT_MODEL_ISSUE > 0)
1524 model_serialize(my_index, cpu_model(processor));
1525 system_call_interrupt(processor, cia);
1528 # I.2.4.3 Condition Register Logical Instructions
1530 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
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.449,31./:XL::cror:Condition Register OR
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.193,31./:XL::crxor:Condition Register XOR
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.225,31./:XL::crnand:Condition Register NAND
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.33,31./:XL::crnor:Condition Register NOR
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.289,31./:XL::creqv:Condition Register Equivalent
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.129,31./:XL::crandc:Condition Register AND 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);
1586 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1587 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1588 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1589 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1590 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1591 BLIT32(CR, BT, CR{BA} || !CR{BB});
1592 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1595 # I.2.4.4 Condition Register Field Instruction
1597 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1598 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1599 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1600 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1601 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1602 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1603 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
1607 # I.3.3.2 Fixed-Point Load Instructions
1610 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1611 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1612 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1613 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1614 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1620 *rT = MEM(unsigned, EA, 1);
1621 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1624 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1625 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1626 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1627 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1628 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1634 *rT = MEM(unsigned, EA, 1);
1635 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1637 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1638 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1639 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1640 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1641 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1643 if (RA == 0 || RA == RT)
1644 program_interrupt(processor, cia,
1645 illegal_instruction_program_interrupt);
1647 *rT = MEM(unsigned, EA, 1);
1649 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1651 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1652 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1653 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1654 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1655 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1657 if (RA == 0 || RA == RT)
1658 program_interrupt(processor, cia,
1659 illegal_instruction_program_interrupt);
1661 *rT = MEM(unsigned, EA, 1);
1663 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1665 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1666 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1667 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1668 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1669 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1675 *rT = MEM(unsigned, EA, 2);
1676 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1678 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1679 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1680 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1681 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1682 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1688 *rT = MEM(unsigned, EA, 2);
1689 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1691 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1692 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1693 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1694 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1695 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1697 if (RA == 0 || RA == RT)
1698 program_interrupt(processor, cia,
1699 illegal_instruction_program_interrupt);
1701 *rT = MEM(unsigned, EA, 2);
1703 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1705 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1706 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1707 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1708 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1709 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1711 if (RA == 0 || RA == RT)
1712 program_interrupt(processor, cia,
1713 illegal_instruction_program_interrupt);
1715 *rT = MEM(unsigned, EA, 2);
1717 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1719 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1720 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1721 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1722 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1723 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1729 *rT = MEM(signed, EA, 2);
1730 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1732 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1733 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1734 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1735 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1736 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1742 *rT = MEM(signed, EA, 2);
1743 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1745 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1746 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1747 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1748 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1749 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1751 if (RA == 0 || RA == RT)
1752 program_interrupt(processor, cia,
1753 illegal_instruction_program_interrupt);
1755 *rT = MEM(signed, EA, 2);
1756 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1758 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1759 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1760 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1761 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1762 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1764 if (RA == 0 || RA == RT)
1765 program_interrupt(processor, cia,
1766 illegal_instruction_program_interrupt);
1768 *rT = MEM(signed, EA, 2);
1770 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1772 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1773 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1774 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1775 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1776 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1782 *rT = MEM(unsigned, EA, 4);
1783 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1785 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1786 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1787 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1788 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1789 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1795 *rT = MEM(unsigned, EA, 4);
1796 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1798 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1799 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1800 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1801 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1802 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1804 if (RA == 0 || RA == RT)
1805 program_interrupt(processor, cia,
1806 illegal_instruction_program_interrupt);
1808 *rT = MEM(unsigned, EA, 4);
1810 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1812 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1813 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1814 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1815 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1816 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1818 if (RA == 0 || RA == RT)
1819 program_interrupt(processor, cia,
1820 illegal_instruction_program_interrupt);
1822 *rT = MEM(unsigned, EA, 4);
1824 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1826 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1829 # if (RA == 0) b = 0;
1831 # EA = b + EXTS(DS_0b00);
1832 # *rT = MEM(signed, EA, 4);
1834 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1837 # if (RA == 0) b = 0;
1840 # *rT = MEM(signed, EA, 4);
1842 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1844 # if (RA == 0 || RA == RT)
1845 # program_interrupt(processor, cia
1846 # illegal_instruction_program_interrupt);
1848 # *rT = MEM(signed, EA, 4);
1851 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1854 # if (RA == 0) b = 0;
1856 # EA = b + EXTS(DS_0b00);
1857 # *rT = MEM(unsigned, EA, 8);
1859 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1862 # if (RA == 0) b = 0;
1865 # *rT = MEM(unsigned, EA, 8);
1867 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1869 # if (RA == 0 || RA == RT)
1870 # program_interrupt(processor, cia
1871 # illegal_instruction_program_interrupt);
1872 # EA = *rA + EXTS(DS_0b00);
1873 # *rT = MEM(unsigned, EA, 8);
1876 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1878 # if (RA == 0 || RA == RT)
1879 # program_interrupt(processor, cia
1880 # illegal_instruction_program_interrupt);
1882 # *rT = MEM(unsigned, EA, 8);
1888 # I.3.3.3 Fixed-Point Store Instructions
1891 0.38,6.RS,11.RA,16.D:D:::Store Byte
1892 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1893 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1894 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1895 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1902 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1904 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1905 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1906 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1907 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1908 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1915 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1917 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1918 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1919 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1920 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1921 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1924 program_interrupt(processor, cia,
1925 illegal_instruction_program_interrupt);
1929 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1931 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1932 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1933 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1934 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1935 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1938 program_interrupt(processor, cia,
1939 illegal_instruction_program_interrupt);
1943 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1945 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1946 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1947 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1948 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1949 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1956 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1958 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1959 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1960 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1961 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1962 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1969 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1971 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1972 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1973 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1974 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1975 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1978 program_interrupt(processor, cia,
1979 illegal_instruction_program_interrupt);
1983 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1985 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1986 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1987 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1988 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1989 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1992 program_interrupt(processor, cia,
1993 illegal_instruction_program_interrupt);
1997 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1999 0.36,6.RS,11.RA,16.D:D:::Store Word
2000 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2001 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2002 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2003 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2010 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
2012 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
2013 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2014 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2015 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2016 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2023 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2025 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
2026 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2027 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2028 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2029 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2032 program_interrupt(processor, cia,
2033 illegal_instruction_program_interrupt);
2037 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2039 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
2040 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2041 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2042 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2043 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2046 program_interrupt(processor, cia,
2047 illegal_instruction_program_interrupt);
2051 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2053 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2056 # if (RA == 0) b = 0;
2058 # EA = b + EXTS(DS_0b00);
2059 # STORE(EA, 8, *rS);
2060 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2063 # if (RA == 0) b = 0;
2066 # STORE(EA, 8, *rS);
2067 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2070 # program_interrupt(processor, cia
2071 # illegal_instruction_program_interrupt);
2072 # EA = *rA + EXTS(DS_0b00);
2073 # STORE(EA, 8, *rS);
2075 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2078 # program_interrupt(processor, cia
2079 # illegal_instruction_program_interrupt);
2081 # STORE(EA, 8, *rS);
2086 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2089 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2090 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2091 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2092 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2093 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2099 *rT = SWAP_2(MEM(unsigned, EA, 2));
2100 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2102 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2103 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2104 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2105 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2106 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2112 *rT = SWAP_4(MEM(unsigned, EA, 4));
2113 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2115 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2116 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2117 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2118 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2119 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2125 STORE(EA, 2, SWAP_2(*rS));
2126 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2128 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2129 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2130 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2131 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2132 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2138 STORE(EA, 4, SWAP_4(*rS));
2139 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2143 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2146 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
2148 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2152 # I.3.3.6 Fixed-Point Move Assist Instructions
2155 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
2157 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2159 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
2161 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2165 # I.3.3.7 Storage Synchronization Instructions
2167 # HACK: Rather than monitor addresses looking for a reason
2168 # to cancel a reservation. This code instead keeps
2169 # a copy of the data read from memory. Before performing
2170 # a store, the memory area is checked to see if it has
2172 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2173 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2174 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2175 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2176 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2183 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2184 RESERVE_DATA = MEM(unsigned, EA, 4);
2186 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2188 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2195 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2196 RESERVE_DATA = MEM(unsigned, EA, 8);
2198 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2200 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2201 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2202 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2203 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2204 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2211 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2212 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2214 CR_SET_XER_SO(0, cr_i_zero);
2217 /* ment to randomly to store, we never do! */
2218 CR_SET_XER_SO(0, 0);
2223 CR_SET_XER_SO(0, 0);
2225 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2227 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2234 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2235 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2237 CR_SET_XER_SO(0, cr_i_zero);
2240 /* ment to randomly to store, we never do */
2241 CR_SET_XER_SO(0, 0);
2246 CR_SET_XER_SO(0, 0);
2248 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2250 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2251 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2252 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2253 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2254 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2259 # I.3.3.9 Fixed-Point Arithmetic Instructions
2262 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
2263 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2264 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2265 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2266 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2267 if (RA_is_0) *rT = EXTS(SI);
2268 else *rT = *rA + EXTS(SI);
2269 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2270 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2272 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
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
2277 if (RA_is_0) *rT = EXTS(SI) << 16;
2278 else *rT = *rA + (EXTS(SI) << 16);
2279 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2280 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2282 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
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_SRU, 1, 1, 0
2286 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2289 ALU_END(*rT, 0/*CA*/, OE, Rc);
2290 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2292 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2293 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2294 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2295 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2296 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2301 ALU_END(*rT, 0/*CA*/, OE, Rc);
2302 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2304 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
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*/, 0/*Rc*/);
2312 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2314 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
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
2321 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2322 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
2324 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2325 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2326 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2327 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2328 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2333 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2334 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2336 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add 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
2343 ALU_END(*rT, 1/*CA*/, OE, Rc);
2344 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2346 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2347 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2348 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2349 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2350 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2351 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2356 ALU_END(*rT, 1/*CA*/, OE, Rc);
2357 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2359 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2360 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2361 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2362 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2363 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2367 ALU_END(*rT, 1/*CA*/, OE, Rc);
2368 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2370 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2371 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2372 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2373 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2374 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2379 ALU_END(*rT, 1/*CA*/, OE, Rc);
2380 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2382 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to 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
2390 ALU_END(*rT, 1/*CA*/, OE, Rc);
2391 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2393 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One 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
2402 ALU_END(*rT, 1/*CA*/, OE, Rc);
2403 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2405 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2406 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2407 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2408 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2409 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2412 ALU_END(*rT, 1/*CA*/, OE, Rc);
2413 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2415 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2416 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2417 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2418 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2419 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2423 ALU_END(*rT, 1/*CA*/, OE, Rc);
2424 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2426 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2427 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2428 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2429 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2430 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2434 ALU_END(*rT,0/*CA*/,OE,Rc);
2435 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2437 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2438 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2439 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2440 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2441 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2442 signed_word prod = *rA * EXTS(SI);
2444 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2446 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2448 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2449 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2450 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2451 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2452 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2453 signed64 a = (signed32)(*rA);
2454 signed64 b = (signed32)(*rB);
2455 signed64 prod = a * b;
2456 signed_word t = prod;
2458 if (t != prod && OE)
2459 XER |= (xer_overflow | xer_summary_overflow);
2460 CR0_COMPARE(t, 0, Rc);
2461 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2463 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2465 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2466 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2467 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2468 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2469 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2470 signed64 a = (signed32)(*rA);
2471 signed64 b = (signed32)(*rB);
2472 signed64 prod = a * b;
2473 signed_word t = EXTRACTED64(prod, 0, 31);
2475 CR0_COMPARE(t, 0, Rc);
2476 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2478 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2480 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2481 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2482 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2483 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2484 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2485 unsigned64 a = (unsigned32)(*rA);
2486 unsigned64 b = (unsigned32)(*rB);
2487 unsigned64 prod = a * b;
2488 signed_word t = EXTRACTED64(prod, 0, 31);
2490 CR0_COMPARE(t, 0, Rc);
2491 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2493 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2495 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2496 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2497 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2498 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2499 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2500 signed64 dividend = (signed32)(*rA);
2501 signed64 divisor = (signed32)(*rB);
2502 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2503 || (dividend == 0x80000000 && divisor == -1)) {
2505 XER |= (xer_overflow | xer_summary_overflow);
2506 CR0_COMPARE(0, 0, Rc);
2509 signed64 quotent = dividend / divisor;
2511 CR0_COMPARE((signed_word)quotent, 0, Rc);
2513 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2515 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2517 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2518 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2519 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2520 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2521 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2522 unsigned64 dividend = (unsigned32)(*rA);
2523 unsigned64 divisor = (unsigned32)(*rB);
2526 XER |= (xer_overflow | xer_summary_overflow);
2527 CR0_COMPARE(0, 0, Rc);
2530 unsigned64 quotent = dividend / divisor;
2532 CR0_COMPARE((signed_word)quotent, 0, Rc);
2534 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2538 # I.3.3.10 Fixed-Point Compare Instructions
2541 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2542 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2543 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2544 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2545 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2546 if (!is_64bit_mode && L)
2547 program_interrupt(processor, cia,
2548 illegal_instruction_program_interrupt);
2551 signed_word b = EXTS(SI);
2556 CR_COMPARE(BF, a, b);
2558 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2560 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2561 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2562 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2563 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2564 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2565 if (!is_64bit_mode && L)
2566 program_interrupt(processor, cia,
2567 illegal_instruction_program_interrupt);
2579 CR_COMPARE(BF, a, b);
2581 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2583 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2584 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2585 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2586 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2587 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2588 if (!is_64bit_mode && L)
2589 program_interrupt(processor, cia,
2590 illegal_instruction_program_interrupt);
2593 unsigned_word b = UI;
2595 a = MASKED(*rA, 32, 63);
2598 CR_COMPARE(BF, a, b);
2600 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2602 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2603 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2604 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2605 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2606 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2607 if (!is_64bit_mode && L)
2608 program_interrupt(processor, cia,
2609 illegal_instruction_program_interrupt);
2614 a = MASKED(*rA, 32, 63);
2615 b = MASKED(*rB, 32, 63);
2621 CR_COMPARE(BF, a, b);
2623 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2627 # I.3.3.11 Fixed-Point Trap Instructions
2630 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2632 program_interrupt(processor, cia,
2633 illegal_instruction_program_interrupt);
2635 signed_word a = *rA;
2636 signed_word b = EXTS(SI);
2637 if ((a < b && TO{0})
2639 || (a == b && TO{2})
2640 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2641 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2643 program_interrupt(processor, cia,
2644 trap_program_interrupt);
2647 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2648 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2649 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2650 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2651 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2652 signed_word a = EXTENDED(*rA);
2653 signed_word b = EXTS(SI);
2654 if ((a < b && TO{0})
2656 || (a == b && TO{2})
2657 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2658 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2660 program_interrupt(processor, cia,
2661 trap_program_interrupt);
2663 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2665 program_interrupt(processor, cia,
2666 illegal_instruction_program_interrupt);
2668 signed_word a = *rA;
2669 signed_word b = *rB;
2670 if ((a < b && TO{0})
2672 || (a == b && TO{2})
2673 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2674 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2676 program_interrupt(processor, cia,
2677 trap_program_interrupt);
2680 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2681 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2682 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2683 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2684 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2685 signed_word a = EXTENDED(*rA);
2686 signed_word b = EXTENDED(*rB);
2687 if (TO == 12 && rA == rB) {
2688 ITRACE(trace_breakpoint, ("breakpoint\n"));
2689 cpu_halt(processor, cia, was_trap, 0);
2691 else if ((a < b && TO{0})
2693 || (a == b && TO{2})
2694 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2695 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2697 program_interrupt(processor, cia,
2698 trap_program_interrupt);
2701 # I.3.3.12 Fixed-Point Logical Instructions
2704 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2705 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2706 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2707 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2708 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2710 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2711 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2712 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2714 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2715 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2716 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2717 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2718 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2719 *rA = *rS & (UI << 16);
2720 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2721 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2722 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2724 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2725 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2726 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2727 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2728 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2730 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2731 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2733 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2734 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2735 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2736 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2737 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2738 *rA = *rS | (UI << 16);
2739 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2740 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2742 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
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 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2749 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2751 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
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
2756 *rA = *rS ^ (UI << 16);
2757 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2758 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2760 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
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 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2768 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2770 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
2771 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2772 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2773 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2774 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2776 CR0_COMPARE(*rA, 0, Rc);
2777 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2778 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2780 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
2781 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2782 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2783 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2784 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2786 CR0_COMPARE(*rA, 0, Rc);
2787 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2788 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2790 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
2791 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2792 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2793 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2794 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2796 CR0_COMPARE(*rA, 0, Rc);
2797 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2798 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2800 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
2801 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2802 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2803 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2804 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2806 CR0_COMPARE(*rA, 0, Rc);
2807 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2808 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2810 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
2811 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2812 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2813 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2814 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2815 *rA = ~(*rS ^ *rB); /* A === B */
2816 CR0_COMPARE(*rA, 0, Rc);
2817 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2818 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2820 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
2821 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2822 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2823 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2824 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2826 CR0_COMPARE(*rA, 0, Rc);
2827 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2828 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2830 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
2831 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2832 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2833 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2834 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2836 CR0_COMPARE(*rA, 0, Rc);
2837 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2838 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2840 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
2841 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2842 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2843 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2844 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2845 *rA = (signed_word)(signed8)*rS;
2846 CR0_COMPARE(*rA, 0, Rc);
2847 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2848 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2850 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half 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
2855 *rA = (signed_word)(signed16)*rS;
2856 CR0_COMPARE(*rA, 0, Rc);
2857 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2858 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2860 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2861 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2862 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2863 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2864 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2865 # *rA = (signed_word)(signed32)*rS;
2866 # CR0_COMPARE(*rA, 0, Rc);
2868 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2870 # unsigned64 mask = BIT64(0);
2871 # unsigned64 source = *rS;
2872 # while (!(source & mask) && mask != 0) {
2877 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2879 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
2880 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2881 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2882 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2883 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2885 unsigned32 mask = BIT32(0);
2886 unsigned32 source = *rS;
2887 while (!(source & mask) && mask != 0) {
2892 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2893 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2897 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2900 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
2901 # long n = (sh_5 << 4) | sh_0_4;
2902 # unsigned_word r = ROTL64(*rS, n);
2903 # long b = (mb_5 << 4) | mb_0_4;
2904 # unsigned_word m = MASK(b, 63);
2905 # signed_word result = r & m;
2907 # ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2908 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2910 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
2911 # long n = (sh_5 << 4) | sh_0_4;
2912 # unsigned_word r = ROTL64(*rS, n);
2913 # long e = (me_5 << 4) | me_0_4;
2914 # unsigned_word m = MASK(0, e);
2915 # signed_word result = r & m;
2917 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2919 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
2920 # long n = (sh_5 << 4) | sh_0_4;
2921 # unsigned_word r = ROTL64(*rS, n);
2922 # long b = (mb_5 << 4) | mb_0_4;
2923 # unsigned_word m = MASK(0, (64-n));
2924 # signed_word result = r & m;
2926 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2928 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2929 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2930 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2931 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2932 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2935 unsigned32 r = ROTL32(s, n);
2936 unsigned32 m = MASK(MB+32, ME+32);
2937 signed_word result = r & m;
2939 CR0_COMPARE(result, 0, Rc);
2941 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
2942 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
2943 (unsigned long)result, (unsigned long)CR));
2944 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2946 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2947 # long n = MASKED(*rB, 58, 63);
2948 # unsigned_word r = ROTL64(*rS, n);
2949 # long b = (mb_5 << 4) | mb_0_4;
2950 # unsigned_word m = MASK(b, 63);
2951 # signed_word result = r & m;
2953 # CR0_COMPARE(result, 0, Rc);
2955 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2956 # long n = MASKED(*rB, 58, 63);
2957 # unsigned_word r = ROTL64(*rS, n);
2958 # long e = (me_5 << 4) | me_0_4;
2959 # unsigned_word m = MASK(0, e);
2960 # signed_word result = r & m;
2962 # CR0_COMPARE(result, 0, Rc);
2964 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2965 # long n = MASKED(*rB, 59, 63);
2966 # unsigned32 r = ROTL32(*rS, n);
2967 # unsigned32 m = MASK(MB+32, ME+32);
2968 # signed_word result = r & m;
2970 # CR0_COMPARE(result, 0, Rc);
2972 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
2973 # long n = (sh_5 << 4) | sh_0_4;
2974 # unsigned_word r = ROTL64(*rS, n);
2975 # long b = (mb_5 << 4) | mb_0_4;
2976 # unsigned_word m = MASK(b, (64-n));
2977 # signed_word result = (r & m) | (*rA & ~m)
2979 # CR0_COMPARE(result, 0, Rc);
2981 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2982 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2983 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2984 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2985 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2987 unsigned32 r = ROTL32(*rS, n);
2988 unsigned32 m = MASK(MB+32, ME+32);
2989 signed_word result = (r & m) | (*rA & ~m);
2991 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
2992 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
2993 (unsigned long)result));
2994 CR0_COMPARE(result, 0, Rc);
2995 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2998 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
3000 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
3001 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3002 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3003 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3004 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3005 int n = MASKED(*rB, 59, 63);
3006 unsigned32 source = *rS;
3007 signed_word shifted;
3009 shifted = (source << n);
3013 CR0_COMPARE(shifted, 0, Rc);
3015 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3016 n, (unsigned long)source, (unsigned long)shifted));
3017 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3019 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3021 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
3022 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3023 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3024 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3025 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3026 int n = MASKED(*rB, 59, 63);
3027 unsigned32 source = *rS;
3028 signed_word shifted;
3030 shifted = (source >> n);
3034 CR0_COMPARE(shifted, 0, Rc);
3036 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3037 n, (unsigned long)source, (unsigned long)shifted));
3038 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3040 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3042 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3043 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3044 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3045 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3046 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3048 signed_word r = ROTL32(*rS, /*64*/32-n);
3049 signed_word m = MASK(n+32, 63);
3050 int S = MASKED(*rS, 32, 32);
3051 signed_word shifted = (r & m) | (S ? ~m : 0);
3053 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3057 CR0_COMPARE(shifted, 0, Rc);
3058 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3059 (long)*rA, (long)*rA, (long)XER));
3060 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3062 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3064 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3065 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3066 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3067 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3068 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3069 int n = MASKED(*rB, 58, 63);
3070 int shift = (n >= 31 ? 31 : n);
3071 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3072 signed32 shifted = source >> shift;
3073 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
3074 *rA = (signed_word)shifted; /* if 64bit will sign extend */
3075 if (source < 0 && (source & mask))
3079 CR0_COMPARE(shifted, 0, Rc);
3080 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3081 (long)*rA, (long)*rA, (long)XER));
3082 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3085 # I.3.3.14 Move to/from System Register Instructions
3088 0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3089 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3090 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3091 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3092 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3093 int n = (SPR{5:9} << 5) | SPR{0:4};
3094 if (SPR{0} && IS_PROBLEM_STATE(processor))
3095 program_interrupt(processor, cia,
3096 privileged_instruction_program_interrupt);
3097 else if (!spr_is_valid(n)
3098 || spr_is_readonly(n))
3099 program_interrupt(processor, cia,
3100 illegal_instruction_program_interrupt);
3102 spreg new_val = (spr_length(n) == 64
3104 : MASKED(*rS, 32, 63));
3105 /* HACK - time base registers need to be updated immediatly */
3106 if (WITH_TIME_BASE) {
3109 cpu_set_time_base(processor,
3110 (MASKED64(cpu_get_time_base(processor), 32, 63)
3111 | INSERTED64(new_val, 0, 31)));
3114 cpu_set_time_base(processor,
3115 (MASKED64(cpu_get_time_base(processor), 0, 31)
3116 | INSERTED64(new_val, 32, 63)));
3119 cpu_set_decrementer(processor, new_val);
3130 PPC_INSN_TO_SPR(RS_BITMASK, n);
3132 0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3133 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3134 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3135 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3136 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3137 int n = (SPR{5:9} << 5) | SPR{0:4};
3138 if (SPR{0} && IS_PROBLEM_STATE(processor))
3139 program_interrupt(processor, cia,
3140 privileged_instruction_program_interrupt);
3141 else if (!spr_is_valid(n))
3142 program_interrupt(processor, cia,
3143 illegal_instruction_program_interrupt);
3145 /* HACK - some SPR's need to get their value extracted specially */
3148 PPC_INSN_FROM_SPR(RT_BITMASK, n);
3150 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3151 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3152 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3153 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3154 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3159 unsigned_word mask = 0;
3161 for (f = 0; f < 8; f++) {
3162 if (FXM & (0x80 >> f))
3163 mask |= (0xf << 4*(7-f));
3165 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3167 PPC_INSN_MTCR(RS_BITMASK, FXM);
3169 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3171 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3172 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3173 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3174 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3175 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3176 *rT = (unsigned32)CR;
3177 PPC_INSN_MFCR(RT_BITMASK);
3180 # I.4.6.2 Floating-Point Load Instructions
3183 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3184 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3185 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3186 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3187 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3193 *frT = DOUBLE(MEM(unsigned, EA, 4));
3194 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3196 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3197 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3198 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3199 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3200 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3206 *frT = DOUBLE(MEM(unsigned, EA, 4));
3207 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3209 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3210 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3211 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3212 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3213 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3216 program_interrupt(processor, cia,
3217 illegal_instruction_program_interrupt);
3219 *frT = DOUBLE(MEM(unsigned, EA, 4));
3221 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3223 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3224 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3225 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3226 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3227 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3230 program_interrupt(processor, cia,
3231 illegal_instruction_program_interrupt);
3233 *frT = DOUBLE(MEM(unsigned, EA, 4));
3235 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3237 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3238 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3239 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3240 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3241 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3247 *frT = MEM(unsigned, EA, 8);
3248 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3250 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3251 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3252 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3253 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3254 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3260 *frT = MEM(unsigned, EA, 8);
3261 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3263 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3264 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3265 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3266 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3267 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3270 program_interrupt(processor, cia,
3271 illegal_instruction_program_interrupt);
3273 *frT = MEM(unsigned, EA, 8);
3275 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3277 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3278 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3279 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3280 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3281 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3284 program_interrupt(processor, cia,
3285 illegal_instruction_program_interrupt);
3287 *frT = MEM(unsigned, EA, 8);
3289 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3293 # I.4.6.3 Floating-Point Store Instructions
3296 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3297 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3298 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3299 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3300 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3306 STORE(EA, 4, SINGLE(*frS));
3307 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3309 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3310 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3311 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3312 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3313 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3319 STORE(EA, 4, SINGLE(*frS));
3320 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3322 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3323 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3324 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3325 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3326 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3329 program_interrupt(processor, cia,
3330 illegal_instruction_program_interrupt);
3332 STORE(EA, 4, SINGLE(*frS));
3334 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3336 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3337 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3338 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3339 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3340 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3343 program_interrupt(processor, cia,
3344 illegal_instruction_program_interrupt);
3346 STORE(EA, 4, SINGLE(*frS));
3348 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3350 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3351 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3352 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3353 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3354 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3361 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3363 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3364 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3365 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3366 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3367 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3374 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3376 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3377 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3378 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3379 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3380 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3383 program_interrupt(processor, cia,
3384 illegal_instruction_program_interrupt);
3388 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3390 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3391 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3392 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3393 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3394 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3397 program_interrupt(processor, cia,
3398 illegal_instruction_program_interrupt);
3402 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3406 # I.4.6.4 Floating-Point Move Instructions
3409 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3410 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3411 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3412 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3413 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3416 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3418 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3419 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3420 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3421 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3422 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3423 *frT = *frB ^ BIT64(0);
3425 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3427 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3428 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3429 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3430 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3431 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3432 *frT = *frB & ~BIT64(0);
3434 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3436 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3437 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3438 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3439 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3440 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3441 *frT = *frB | BIT64(0);
3443 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3447 # I.4.6.5 Floating-Point Arithmetic Instructions
3450 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3451 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3452 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3453 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3454 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3456 if (is_invalid_operation(processor, cia,
3458 fpscr_vxsnan | fpscr_vxisi,
3461 invalid_arithemetic_operation(processor, cia,
3463 0, /*instruction_is_frsp*/
3464 0, /*instruction_is_convert_to_64bit*/
3465 0, /*instruction_is_convert_to_32bit*/
3466 0); /*single-precision*/
3470 double s = *(double*)frA + *(double*)frB;
3474 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3476 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3477 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3478 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3479 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3480 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3482 if (is_invalid_operation(processor, cia,
3484 fpscr_vxsnan | fpscr_vxisi,
3487 invalid_arithemetic_operation(processor, cia,
3489 0, /*instruction_is_frsp*/
3490 0, /*instruction_is_convert_to_64bit*/
3491 0, /*instruction_is_convert_to_32bit*/
3492 1); /*single-precision*/
3496 float s = *(double*)frA + *(double*)frB;
3500 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3502 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3503 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3504 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3505 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3506 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3508 if (is_invalid_operation(processor, cia,
3510 fpscr_vxsnan | fpscr_vxisi,
3513 invalid_arithemetic_operation(processor, cia,
3515 0, /*instruction_is_frsp*/
3516 0, /*instruction_is_convert_to_64bit*/
3517 0, /*instruction_is_convert_to_32bit*/
3518 0); /*single-precision*/
3522 double s = *(double*)frA - *(double*)frB;
3526 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3528 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3529 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3530 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3531 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3532 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3534 if (is_invalid_operation(processor, cia,
3536 fpscr_vxsnan | fpscr_vxisi,
3539 invalid_arithemetic_operation(processor, cia,
3541 0, /*instruction_is_frsp*/
3542 0, /*instruction_is_convert_to_64bit*/
3543 0, /*instruction_is_convert_to_32bit*/
3544 1); /*single-precision*/
3548 float s = *(double*)frA - *(double*)frB;
3552 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3554 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3555 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3556 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3557 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3558 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3560 if (is_invalid_operation(processor, cia,
3562 fpscr_vxsnan | fpscr_vximz,
3565 invalid_arithemetic_operation(processor, cia,
3567 0, /*instruction_is_frsp*/
3568 0, /*instruction_is_convert_to_64bit*/
3569 0, /*instruction_is_convert_to_32bit*/
3570 0); /*single-precision*/
3574 double s = *(double*)frA * *(double*)frC;
3578 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3580 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3581 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3582 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3583 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3584 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3586 if (is_invalid_operation(processor, cia,
3588 fpscr_vxsnan | fpscr_vximz,
3591 invalid_arithemetic_operation(processor, cia,
3593 0, /*instruction_is_frsp*/
3594 0, /*instruction_is_convert_to_64bit*/
3595 0, /*instruction_is_convert_to_32bit*/
3596 1); /*single-precision*/
3600 float s = *(double*)frA * *(double*)frC;
3604 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3606 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3607 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3608 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3609 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3610 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3612 if (is_invalid_operation(processor, cia,
3614 fpscr_vxsnan | fpscr_vxzdz,
3617 invalid_arithemetic_operation(processor, cia,
3619 0, /*instruction_is_frsp*/
3620 0, /*instruction_is_convert_to_64bit*/
3621 0, /*instruction_is_convert_to_32bit*/
3622 0); /*single-precision*/
3626 double s = *(double*)frA / *(double*)frB;
3630 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3632 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3633 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3634 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3635 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3636 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3638 if (is_invalid_operation(processor, cia,
3640 fpscr_vxsnan | fpscr_vxzdz,
3643 invalid_arithemetic_operation(processor, cia,
3645 0, /*instruction_is_frsp*/
3646 0, /*instruction_is_convert_to_64bit*/
3647 0, /*instruction_is_convert_to_32bit*/
3648 1); /*single-precision*/
3652 float s = *(double*)frA / *(double*)frB;
3656 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3658 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3659 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3660 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3661 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3662 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3664 double product; /*HACK! - incorrectly loosing precision ... */
3665 /* compute the multiply */
3666 if (is_invalid_operation(processor, cia,
3668 fpscr_vxsnan | fpscr_vximz,
3671 invalid_arithemetic_operation(processor, cia,
3672 (unsigned64*)&product, *frA, 0, *frC,
3673 0, /*instruction_is_frsp*/
3674 0, /*instruction_is_convert_to_64bit*/
3675 0, /*instruction_is_convert_to_32bit*/
3676 0); /*single-precision*/
3680 product = *(double*)frA * *(double*)frC;
3682 /* compute the add */
3683 if (is_invalid_operation(processor, cia,
3685 fpscr_vxsnan | fpscr_vxisi,
3688 invalid_arithemetic_operation(processor, cia,
3689 frT, product, *frB, 0,
3690 0, /*instruction_is_frsp*/
3691 0, /*instruction_is_convert_to_64bit*/
3692 0, /*instruction_is_convert_to_32bit*/
3693 0); /*single-precision*/
3697 double s = product + *(double*)frB;
3701 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3703 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3704 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3705 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3706 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3707 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3709 float product; /*HACK! - incorrectly loosing precision ... */
3710 /* compute the multiply */
3711 if (is_invalid_operation(processor, cia,
3713 fpscr_vxsnan | fpscr_vximz,
3716 invalid_arithemetic_operation(processor, cia,
3717 (unsigned64*)&product, *frA, 0, *frC,
3718 0, /*instruction_is_frsp*/
3719 0, /*instruction_is_convert_to_64bit*/
3720 0, /*instruction_is_convert_to_32bit*/
3721 0); /*single-precision*/
3725 product = *(double*)frA * *(double*)frC;
3727 /* compute the add */
3728 if (is_invalid_operation(processor, cia,
3730 fpscr_vxsnan | fpscr_vxisi,
3733 invalid_arithemetic_operation(processor, cia,
3734 frT, product, *frB, 0,
3735 0, /*instruction_is_frsp*/
3736 0, /*instruction_is_convert_to_64bit*/
3737 0, /*instruction_is_convert_to_32bit*/
3738 0); /*single-precision*/
3742 float s = product + *(double*)frB;
3743 *(double*)frT = (double)s;
3746 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3748 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3749 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3750 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3751 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3752 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3754 double product; /*HACK! - incorrectly loosing precision ... */
3755 /* compute the multiply */
3756 if (is_invalid_operation(processor, cia,
3758 fpscr_vxsnan | fpscr_vximz,
3761 invalid_arithemetic_operation(processor, cia,
3762 (unsigned64*)&product, *frA, 0, *frC,
3763 0, /*instruction_is_frsp*/
3764 0, /*instruction_is_convert_to_64bit*/
3765 0, /*instruction_is_convert_to_32bit*/
3766 0); /*single-precision*/
3770 product = *(double*)frA * *(double*)frC;
3772 /* compute the subtract */
3773 if (is_invalid_operation(processor, cia,
3775 fpscr_vxsnan | fpscr_vxisi,
3778 invalid_arithemetic_operation(processor, cia,
3779 frT, product, *frB, 0,
3780 0, /*instruction_is_frsp*/
3781 0, /*instruction_is_convert_to_64bit*/
3782 0, /*instruction_is_convert_to_32bit*/
3783 0); /*single-precision*/
3787 double s = product - *(double*)frB;
3791 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3793 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
3794 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3795 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3796 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3797 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3799 float product; /*HACK! - incorrectly loosing precision ... */
3800 /* compute the multiply */
3801 if (is_invalid_operation(processor, cia,
3803 fpscr_vxsnan | fpscr_vximz,
3806 invalid_arithemetic_operation(processor, cia,
3807 (unsigned64*)&product, *frA, 0, *frC,
3808 0, /*instruction_is_frsp*/
3809 0, /*instruction_is_convert_to_64bit*/
3810 0, /*instruction_is_convert_to_32bit*/
3811 0); /*single-precision*/
3815 product = *(double*)frA * *(double*)frC;
3817 /* compute the subtract */
3818 if (is_invalid_operation(processor, cia,
3820 fpscr_vxsnan | fpscr_vxisi,
3823 invalid_arithemetic_operation(processor, cia,
3824 frT, product, *frB, 0,
3825 0, /*instruction_is_frsp*/
3826 0, /*instruction_is_convert_to_64bit*/
3827 0, /*instruction_is_convert_to_32bit*/
3828 0); /*single-precision*/
3832 float s = product - *(double*)frB;
3833 *(double*)frT = (double)s;
3836 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3838 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
3839 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3840 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3841 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3842 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3844 double product; /*HACK! - incorrectly loosing precision ... */
3845 /* compute the multiply */
3846 if (is_invalid_operation(processor, cia,
3848 fpscr_vxsnan | fpscr_vximz,
3851 invalid_arithemetic_operation(processor, cia,
3852 (unsigned64*)&product, *frA, 0, *frC,
3853 0, /*instruction_is_frsp*/
3854 0, /*instruction_is_convert_to_64bit*/
3855 0, /*instruction_is_convert_to_32bit*/
3856 0); /*single-precision*/
3860 product = *(double*)frA * *(double*)frC;
3862 /* compute the add */
3863 if (is_invalid_operation(processor, cia,
3865 fpscr_vxsnan | fpscr_vxisi,
3868 invalid_arithemetic_operation(processor, cia,
3869 frT, product, *frB, 0,
3870 0, /*instruction_is_frsp*/
3871 0, /*instruction_is_convert_to_64bit*/
3872 0, /*instruction_is_convert_to_32bit*/
3873 0); /*single-precision*/
3877 double s = -(product + *(double*)frB);
3881 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3883 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
3884 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3885 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3886 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3887 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3889 float product; /*HACK! - incorrectly loosing precision ... */
3890 /* compute the multiply */
3891 if (is_invalid_operation(processor, cia,
3893 fpscr_vxsnan | fpscr_vximz,
3896 invalid_arithemetic_operation(processor, cia,
3897 (unsigned64*)&product, *frA, 0, *frC,
3898 0, /*instruction_is_frsp*/
3899 0, /*instruction_is_convert_to_64bit*/
3900 0, /*instruction_is_convert_to_32bit*/
3901 0); /*single-precision*/
3905 product = *(double*)frA * *(double*)frC;
3907 /* compute the add */
3908 if (is_invalid_operation(processor, cia,
3910 fpscr_vxsnan | fpscr_vxisi,
3913 invalid_arithemetic_operation(processor, cia,
3914 frT, product, *frB, 0,
3915 0, /*instruction_is_frsp*/
3916 0, /*instruction_is_convert_to_64bit*/
3917 0, /*instruction_is_convert_to_32bit*/
3918 0); /*single-precision*/
3922 float s = -(product + *(double*)frB);
3923 *(double*)frT = (double)s;
3926 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3928 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
3929 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3930 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3931 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3932 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3934 double product; /*HACK! - incorrectly loosing precision ... */
3935 /* compute the multiply */
3936 if (is_invalid_operation(processor, cia,
3938 fpscr_vxsnan | fpscr_vximz,
3941 invalid_arithemetic_operation(processor, cia,
3942 (unsigned64*)&product, *frA, 0, *frC,
3943 0, /*instruction_is_frsp*/
3944 0, /*instruction_is_convert_to_64bit*/
3945 0, /*instruction_is_convert_to_32bit*/
3946 0); /*single-precision*/
3950 product = *(double*)frA * *(double*)frC;
3952 /* compute the subtract */
3953 if (is_invalid_operation(processor, cia,
3955 fpscr_vxsnan | fpscr_vxisi,
3958 invalid_arithemetic_operation(processor, cia,
3959 frT, product, *frB, 0,
3960 0, /*instruction_is_frsp*/
3961 0, /*instruction_is_convert_to_64bit*/
3962 0, /*instruction_is_convert_to_32bit*/
3963 0); /*single-precision*/
3967 double s = -(product - *(double*)frB);
3971 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3973 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
3974 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3975 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3976 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3977 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3979 float product; /*HACK! - incorrectly loosing precision ... */
3980 /* compute the multiply */
3981 if (is_invalid_operation(processor, cia,
3983 fpscr_vxsnan | fpscr_vximz,
3986 invalid_arithemetic_operation(processor, cia,
3987 (unsigned64*)&product, *frA, 0, *frC,
3988 0, /*instruction_is_frsp*/
3989 0, /*instruction_is_convert_to_64bit*/
3990 0, /*instruction_is_convert_to_32bit*/
3991 0); /*single-precision*/
3995 product = *(double*)frA * *(double*)frC;
3997 /* compute the subtract */
3998 if (is_invalid_operation(processor, cia,
4000 fpscr_vxsnan | fpscr_vxisi,
4003 invalid_arithemetic_operation(processor, cia,
4004 frT, product, *frB, 0,
4005 0, /*instruction_is_frsp*/
4006 0, /*instruction_is_convert_to_64bit*/
4007 0, /*instruction_is_convert_to_32bit*/
4008 0); /*single-precision*/
4012 float s = -(product - *(double*)frB);
4013 *(double*)frT = (double)s;
4016 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4020 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4023 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4024 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4025 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4026 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4027 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4030 unsigned64 frac_grx;
4031 /* split off cases for what to do */
4032 if (EXTRACTED64(*frB, 1, 11) < 897
4033 && EXTRACTED64(*frB, 1, 63) > 0) {
4034 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
4035 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
4037 if (EXTRACTED64(*frB, 1, 11) > 1150
4038 && EXTRACTED64(*frB, 1, 11) < 2047) {
4039 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4040 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
4042 if (EXTRACTED64(*frB, 1, 11) > 896
4043 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
4044 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
4045 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4046 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
4047 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
4048 if (EXTRACTED64(*frB, 12, 12) == 0
4049 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
4052 Disabled_Exponent_Underflow:
4053 sign = EXTRACTED64(*frB, 0, 0);
4054 if (EXTRACTED64(*frB, 1, 11) == 0) {
4056 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4058 if (EXTRACTED64(*frB, 1, 11) > 0) {
4059 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4060 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4062 /* G|R|X == zero from above */
4063 while (exp < -126) {
4065 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4066 | MASKED64(frac_grx, 55, 55));
4068 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4069 Round_Single(processor, sign, &exp, &frac_grx);
4070 FPSCR_SET_XX(FPSCR & fpscr_fi);
4071 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4072 *frT = INSERTED64(sign, 0, 0);
4073 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4074 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4076 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4077 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4078 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4079 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4081 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4082 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4083 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4085 /*Normalize_Operand:*/
4086 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4088 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4090 *frT = (INSERTED64(sign, 0, 0)
4091 | INSERTED64(exp + 1023, 1, 11)
4092 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4095 Enabled_Exponent_Underflow:
4097 sign = EXTRACTED64(*frB, 0, 0);
4098 if (EXTRACTED64(*frB, 1, 11) == 0) {
4100 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4102 if (EXTRACTED64(*frB, 1, 11) > 0) {
4103 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4104 frac_grx = (BIT64(0) |
4105 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4107 /*Normalize_Operand:*/
4108 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4110 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4112 Round_Single(processor, sign, &exp, &frac_grx);
4113 FPSCR_SET_XX(FPSCR & fpscr_fi);
4115 *frT = (INSERTED64(sign, 0, 0)
4116 | INSERTED64(exp + 1023, 1, 11)
4117 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4118 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4119 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4121 Disabled_Exponent_Overflow:
4123 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4124 if (EXTRACTED64(*frB, 0, 0) == 0) {
4125 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4126 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4128 if (EXTRACTED64(*frB, 0, 0) == 1) {
4129 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4130 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4133 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4134 if (EXTRACTED64(*frB, 0, 0) == 0) {
4135 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4136 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4138 if (EXTRACTED64(*frB, 0, 0) == 1) {
4139 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4140 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4143 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4144 if (EXTRACTED64(*frB, 0, 0) == 0) {
4145 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4146 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4148 if (EXTRACTED64(*frB, 0, 0) == 1) {
4149 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4150 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4153 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4154 if (EXTRACTED64(*frB, 0, 0) == 0) {
4155 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4156 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4158 if (EXTRACTED64(*frB, 0, 0) == 1) {
4159 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4160 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4163 /* FPSCR[FR] <- undefined */
4167 Enabled_Exponent_Overflow:
4168 sign = EXTRACTED64(*frB, 0, 0);
4169 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4170 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4171 Round_Single(processor, sign, &exp, &frac_grx);
4172 FPSCR_SET_XX(FPSCR & fpscr_fi);
4176 *frT = (INSERTED64(sign, 0, 0)
4177 | INSERTED64(exp + 1023, 1, 11)
4178 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4179 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4180 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4184 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4185 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4191 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4192 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4197 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4198 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4203 FPSCR_OR_VX(fpscr_vxsnan);
4204 if ((FPSCR & fpscr_ve) == 0) {
4205 *frT = (MASKED64(*frB, 0, 11)
4207 | MASKED64(*frB, 13, 34));
4208 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4214 sign = EXTRACTED64(*frB, 0, 0);
4215 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4216 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4217 Round_Single(processor, sign, &exp, &frac_grx);
4218 FPSCR_SET_XX(FPSCR & fpscr_fi);
4219 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4220 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4221 *frT = (INSERTED64(sign, 0, 0)
4222 | INSERTED64(exp + 1023, 1, 11)
4223 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4224 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4225 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4228 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4230 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4232 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4234 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4236 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4237 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4238 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4239 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4240 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4242 convert_to_integer(processor, cia,
4244 fpscr_rn_round_towards_zero, 32);
4246 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4248 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4249 int sign = EXTRACTED64(*frB, 0, 0);
4251 unsigned64 frac = *frB;
4252 if (frac == 0) goto Zero_Operand;
4253 if (sign == 1) frac = ~frac + 1;
4254 while (EXTRACTED64(frac, 0, 0) == 0) {
4255 /*??? do the loop 0 times if (FRB) = max negative integer */
4256 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4259 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4260 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4261 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4262 *frT = (INSERTED64(sign, 0, 0)
4263 | INSERTED64(exp + 1023, 1, 11)
4264 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4270 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4275 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4278 # I.4.6.7 Floating-Point Compare Instructions
4281 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4282 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4283 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4284 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4285 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4288 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4289 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4290 else if (is_less_than(frA, frB))
4291 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4292 else if (is_greater_than(frA, frB))
4293 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4295 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4297 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4298 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4299 FPSCR_OR_VX(fpscr_vxsnan);
4301 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4303 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4304 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4305 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4306 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4307 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4310 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4311 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4312 else if (is_less_than(frA, frB))
4313 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4314 else if (is_greater_than(frA, frB))
4315 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4317 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4319 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4320 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4321 FPSCR_OR_VX(fpscr_vxsnan);
4322 if ((FPSCR & fpscr_ve) == 0)
4323 FPSCR_OR_VX(fpscr_vxvc);
4325 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4326 FPSCR_OR_VX(fpscr_vxvc);
4329 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4333 # I.4.6.8 Floating-Point Status and Control Register Instructions
4336 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4338 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4340 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4342 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4344 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4346 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4350 # I.A.1.1 Floating-Point Store Instruction
4352 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4355 # I.A.1.2 Floating-Point Arithmetic Instructions
4358 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
4360 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4362 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
4364 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4367 # I.A.1.3 Floating-Point Select Instruction
4370 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4374 # II.3.2 Cache Management Instructions
4377 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4378 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4379 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4380 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4381 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4382 /* blindly flush all instruction cache entries */
4383 #if WITH_IDECODE_CACHE_SIZE
4384 cpu_flush_icache(processor);
4386 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4388 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4389 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4390 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4391 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4392 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4393 cpu_synchronize_context(processor);
4394 PPC_INSN_INT(0, 0, 0);
4398 # II.3.2.2 Data Cache Instructions
4401 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4402 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4403 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4404 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4405 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4406 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4407 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4409 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4410 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4411 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4412 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4413 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4414 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4415 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4417 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4418 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4419 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4420 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4421 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4422 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4423 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4425 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4426 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4427 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4428 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4429 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4430 TRACE(trace_tbd,("Data Cache Block Store\n"));
4431 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4433 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4434 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4435 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4436 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4437 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4438 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4439 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4442 # II.3.3 Enforce In-order Execution of I/O Instruction
4445 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4446 /* Since this model has no instruction overlap
4447 this instruction need do nothing */
4450 # II.4.1 Time Base Instructions
4453 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4454 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4455 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4456 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4457 int n = (tbr{5:9} << 5) | tbr{0:4};
4459 if (is_64bit_implementation) *rT = TB;
4460 else *rT = EXTRACTED64(TB, 32, 63);
4462 else if (n == 269) {
4463 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4464 else *rT = EXTRACTED64(TB, 0, 31);
4467 program_interrupt(processor, cia,
4468 illegal_instruction_program_interrupt);
4472 # III.2.3.1 System Linkage Instructions
4475 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4476 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4477 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4478 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4479 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4480 if (IS_PROBLEM_STATE(processor)) {
4481 program_interrupt(processor, cia,
4482 privileged_instruction_program_interrupt);
4485 MSR = (MASKED(SRR1, 0, 32)
4486 | MASKED(SRR1, 37, 41)
4487 | MASKED(SRR1, 48, 63));
4488 NIA = MASKED(SRR0, 0, 61);
4489 cpu_synchronize_context(processor);
4493 # III.3.4.1 Move to/from System Register Instructions
4496 #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4497 #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4498 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4499 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4500 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4501 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4502 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4503 if (IS_PROBLEM_STATE(processor))
4504 program_interrupt(processor, cia,
4505 privileged_instruction_program_interrupt);
4509 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4510 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4511 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4512 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4513 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4514 if (IS_PROBLEM_STATE(processor))
4515 program_interrupt(processor, cia,
4516 privileged_instruction_program_interrupt);
4522 # III.4.11.1 Cache Management Instructions
4525 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4526 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4527 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4528 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4529 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4530 if (IS_PROBLEM_STATE(processor))
4531 program_interrupt(processor, cia,
4532 privileged_instruction_program_interrupt);
4534 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4537 # III.4.11.2 Segment Register Manipulation Instructions
4540 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4541 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4542 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4543 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4544 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4545 if (IS_PROBLEM_STATE(processor))
4546 program_interrupt(processor, cia,
4547 privileged_instruction_program_interrupt);
4551 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4552 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4553 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4554 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4555 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4556 if (IS_PROBLEM_STATE(processor))
4557 program_interrupt(processor, cia,
4558 privileged_instruction_program_interrupt);
4560 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4562 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4563 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4564 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4565 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4566 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4567 if (IS_PROBLEM_STATE(processor))
4568 program_interrupt(processor, cia,
4569 privileged_instruction_program_interrupt);
4573 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4574 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4575 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4576 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4577 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4578 if (IS_PROBLEM_STATE(processor))
4579 program_interrupt(processor, cia,
4580 privileged_instruction_program_interrupt);
4582 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4586 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4589 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4591 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4593 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4595 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4597 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4601 # III.A.1.2 External Access Instructions
4604 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4606 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed