2 # This file is part of the program psim.
4 # Copyright (C) 1994-1996, 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.
38 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
39 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
40 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
41 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
45 #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \
47 if (CURRENT_MODEL_ISSUE > 0) { \
49 ppc_insn_int(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
51 ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
55 #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \
57 if (CURRENT_MODEL_ISSUE > 0) \
58 ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
61 #define PPC_INSN_CR(OUT_MASK, IN_MASK) \
63 if (CURRENT_MODEL_ISSUE > 0) \
64 ppc_insn_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
67 #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \
69 if (CURRENT_MODEL_ISSUE > 0) { \
71 ppc_insn_float(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
73 ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
77 #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \
79 if (CURRENT_MODEL_ISSUE > 0) \
80 ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
83 #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \
85 if (CURRENT_MODEL_ISSUE > 0) \
86 ppc_insn_int_float(MY_INDEX, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \
89 #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \
91 if (CURRENT_MODEL_ISSUE > 0) \
92 ppc_insn_from_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
95 #define PPC_INSN_TO_SPR(INT_MASK, SPR) \
97 if (CURRENT_MODEL_ISSUE > 0) \
98 ppc_insn_to_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
101 #define PPC_INSN_MFCR(INT_MASK) \
103 if (CURRENT_MODEL_ISSUE > 0) \
104 ppc_insn_mfcr(MY_INDEX, cpu_model(processor), INT_MASK); \
107 #define PPC_INSN_MTCR(INT_MASK, FXM) \
109 if (CURRENT_MODEL_ISSUE > 0) \
110 ppc_insn_mtcr(MY_INDEX, cpu_model(processor), INT_MASK, FXM); \
114 typedef enum _ppc_function_unit {
115 PPC_UNIT_BAD, /* unknown function unit */
116 PPC_UNIT_IU, /* integer unit (601/603 style) */
117 PPC_UNIT_SRU, /* system register unit (601/603 style) */
118 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
119 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
120 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
121 PPC_UNIT_FPU, /* floating point unit */
122 PPC_UNIT_LSU, /* load/store unit */
123 PPC_UNIT_BPU, /* branch unit */
124 nr_ppc_function_units
127 /* Structure to hold timing information on a per instruction basis */
129 ppc_function_unit first_unit; /* first functional unit this insn could use */
130 ppc_function_unit second_unit; /* second functional unit this insn could use */
131 signed16 issue; /* # cycles before function unit can process other insns */
132 signed16 done; /* # cycles before insn is done */
133 unsigned32 flags; /* any flags that are needed */
136 /* Register mappings in status masks */
137 #define PPC_CR_REG 0 /* start of CR0 .. CR7 */
138 #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */
140 #define PPC_NO_SPR (-1) /* flag for no SPR register */
142 /* Return if 1 bit set */
143 #define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0)
145 /* Structure for each functional unit that is busy */
146 typedef struct _model_busy model_busy;
148 model_busy *next; /* next function unit */
149 ppc_function_unit unit; /* function unit name */
150 unsigned32 int_busy; /* int registers that are busy */
151 unsigned32 fp_busy; /* floating point registers that are busy */
152 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
153 signed16 spr_busy; /* SPR register that is busy or PPC_NO_SPR */
154 signed16 issue; /* # of cycles until unit can accept another insn */
155 signed16 done; /* # of cycles until insn is done */
156 signed16 nr_writebacks; /* # of registers this unit writes back */
159 /* Structure to hold the current state information for the simulated CPU model */
161 cpu *processor; /* point back to processor */
162 const char *name; /* model name */
163 const model_time *timing; /* timing information */
164 model_busy busy_head; /* dummy entry to head list of busy function units */
165 model_busy *busy_tail; /* tail of list of busy function units */
166 model_busy *free_list; /* list of model_busy structs not in use */
167 count_type nr_cycles; /* # cycles */
168 count_type nr_branches; /* # branches */
169 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
170 count_type nr_branch_predict_trues; /* # branches predicted correctly */
171 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
172 count_type nr_branch_conditional[32]; /* # of each type of bc */
173 count_type nr_mtcrf_crs[9]; /* # of CR's moved in a mtcrf instruction */
174 count_type nr_stalls_data; /* # of stalls for data */
175 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
176 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
177 count_type nr_stalls_writeback; /* # of stalls waiting for a writeback slot */
178 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
179 int max_nr_writebacks; /* max # of writeback slots available */
180 unsigned32 int_busy; /* int registers that are busy */
181 unsigned32 fp_busy; /* floating point registers that are busy */
182 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
183 unsigned8 spr_busy[nr_of_sprs]; /* SPR registers that are busy */
184 unsigned8 busy[nr_ppc_function_units]; /* whether a function is busy or not */
187 static const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
188 "unknown functional unit instruction",
189 "integer functional unit instruction",
190 "system register functional unit instruction",
191 "1st single cycle integer functional unit instruction",
192 "2nd single cycle integer functional unit instruction",
193 "multiple cycle integer functional unit instruction",
194 "floating point functional unit instruction",
195 "load/store functional unit instruction",
196 "branch functional unit instruction",
199 static const char *const ppc_branch_conditional_name[32] = {
200 "branch if --CTR != 0 and condition is FALSE", /* 0000y */
201 "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
202 "branch if --CTR == 0 and condition is FALSE", /* 0001y */
203 "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
204 "branch if the condition is FALSE", /* 001zy */
205 "branch if the condition is FALSE, reverse branch likely",
206 "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */
207 "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
208 "branch if --CTR != 0 and condition is TRUE", /* 0100y */
209 "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
210 "branch if --CTR == 0 and condition is TRUE", /* 0101y */
211 "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
212 "branch if the condition is TRUE", /* 011zy */
213 "branch if the condition is TRUE, reverse branch likely",
214 "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */
215 "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
216 "branch if --CTR != 0", /* 1z00y */
217 "branch if --CTR != 0, reverse branch likely",
218 "branch if --CTR == 0", /* 1z01y */
219 "branch if --CTR == 0, reverse branch likely",
220 "branch always", /* 1z1zz */
221 "branch always (ignored bit 5 set to 1)",
222 "branch always (ignored bit 4 set to 1)", /* 1z1zz */
223 "branch always (ignored bits 4,5 set to 1)",
224 "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */
225 "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
226 "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */
227 "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
228 "branch always (ignored bit 1 set to 1)", /* 1z1zz */
229 "branch always (ignored bits 1,5 set to 1)",
230 "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */
231 "branch always (ignored bits 1,4,5 set to 1)",
234 static const char *const ppc_nr_mtcrf_crs[9] = {
235 "mtcrf moving 0 CRs",
237 "mtcrf moving 2 CRs",
238 "mtcrf moving 3 CRs",
239 "mtcrf moving 4 CRs",
240 "mtcrf moving 5 CRs",
241 "mtcrf moving 6 CRs",
242 "mtcrf moving 7 CRs",
243 "mtcrf moving all CRs",
246 # Trace releasing resources
247 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
249 TRACE(trace_model,("done, %s, %d writeback%s\n", ppc_function_unit_name[busy->unit],
250 busy->nr_writebacks, busy->nr_writebacks == 1 ? "" : "s"));
251 if (busy->int_busy) {
252 for(i = 0; i < 32; i++) {
253 if (((1 << i) & busy->int_busy) != 0) {
254 TRACE(trace_model, ("Register r%d is now available.\n", i));
259 for(i = 0; i < 32; i++) {
260 if (((1 << i) & busy->fp_busy) != 0) {
261 TRACE(trace_model, ("Register f%d is now available.\n", i));
265 if (busy->cr_fpscr_busy) {
266 for(i = 0; i < 8; i++) {
267 if (((1 << i) & busy->cr_fpscr_busy) != 0) {
268 TRACE(trace_model, ("Register cr%d is now available.\n", i));
271 if (busy->cr_fpscr_busy & 0x100)
272 TRACE(trace_model, ("Register fpscr is now available.\n"));
274 if (busy->spr_busy != PPC_NO_SPR)
275 TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
277 # Trace making registers busy
278 void::model-static::model_trace_make_busy:model_data *model_ptr, unsigned32 int_mask, unsigned32 fp_mask, unsigned32 cr_mask
281 for(i = 0; i < 32; i++) {
282 if (((1 << i) & int_mask) != 0) {
283 TRACE(trace_model, ("Register r%d is now busy.\n", i));
288 for(i = 0; i < 32; i++) {
289 if (((1 << i) & fp_mask) != 0) {
290 TRACE(trace_model, ("Register f%d is now busy.\n", i));
295 for(i = 0; i < 8; i++) {
296 if (((1 << i) & cr_mask) != 0) {
297 TRACE(trace_model, ("Register cr%d is now busy.\n", i));
302 # Trace waiting for registers to become available
303 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
306 int_busy &= model_ptr->int_busy;
307 for(i = 0; i < 32; i++) {
308 if (((1 << i) & int_busy) != 0) {
309 TRACE(trace_model, ("Waiting for register r%d.\n", i));
314 fp_busy &= model_ptr->fp_busy;
315 for(i = 0; i < 32; i++) {
316 if (((1 << i) & fp_busy) != 0) {
317 TRACE(trace_model, ("Waiting for register f%d.\n", i));
321 if (cr_or_fpscr_busy) {
322 cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
323 for(i = 0; i < 8; i++) {
324 if (((1 << i) & cr_or_fpscr_busy) != 0) {
325 TRACE(trace_model, ("Waiting for register cr%d.\n", i));
328 if (cr_or_fpscr_busy & 0x100)
329 TRACE(trace_model, ("Waiting for register fpscr.\n"));
331 if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
332 TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
334 # Advance state to next cycle, releasing any registers allocated
335 void::model-internal::model_new_cycle:model_data *model_ptr
336 model_busy *cur_busy = model_ptr->busy_head.next;
337 model_busy *free_list = model_ptr->free_list;
338 model_busy *busy_tail = &model_ptr->busy_head;
339 int nr_writebacks = model_ptr->max_nr_writebacks;
342 model_ptr->nr_cycles++;
343 TRACE(trace_model,("New cycle %lu\n", (unsigned long)model_ptr->nr_cycles));
344 for ( ; cur_busy; cur_busy = next) {
345 next = cur_busy->next;
346 if (--cur_busy->done <= 0) { /* function unit done, release registers if we have writeback slots */
347 nr_writebacks -= cur_busy->nr_writebacks;
348 if (nr_writebacks >= 0) {
349 model_ptr->int_busy &= ~cur_busy->int_busy;
350 model_ptr->fp_busy &= ~cur_busy->fp_busy;
351 model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
352 if (cur_busy->spr_busy != PPC_NO_SPR)
353 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
355 if (WITH_TRACE && ppc_trace[trace_model])
356 model_trace_release(model_ptr, cur_busy);
358 model_ptr->busy[cur_busy->unit] = 0;
359 cur_busy->next = free_list;
360 free_list = cur_busy;
362 else { /* writeback slots not available */
363 TRACE(trace_model,("%d writeback slot%s not available for %s\n",
364 cur_busy->nr_writebacks,
365 cur_busy->nr_writebacks == 1 ? " is" : "s are",
366 ppc_function_unit_name[cur_busy->unit]));
367 cur_busy->done++; /* undo -- above */
368 model_ptr->nr_stalls_writeback++;
369 busy_tail->next = cur_busy;
370 busy_tail = cur_busy;
373 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
374 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
375 model_ptr->busy[cur_busy->unit] = 0;
376 busy_tail->next = cur_busy;
377 busy_tail = cur_busy;
380 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
381 ppc_function_unit_name[cur_busy->unit],
384 busy_tail->next = cur_busy;
385 busy_tail = cur_busy;
389 busy_tail->next = (model_busy *)0;
390 model_ptr->busy_tail = busy_tail;
391 model_ptr->free_list = free_list;
393 # Mark a function unit as busy, return the busy structure
394 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
397 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
399 if (!model_ptr->free_list) {
400 busy = ZALLOC(model_busy);
403 busy = model_ptr->free_list;
404 model_ptr->free_list = busy->next;
405 busy->next = (model_busy *)0;
408 busy->cr_fpscr_busy = 0;
409 busy->nr_writebacks = 0;
415 busy->spr_busy = PPC_NO_SPR;
416 model_ptr->busy_tail->next = busy;
417 model_ptr->busy_tail = busy;
418 model_ptr->busy[unit] = 1;
419 model_ptr->nr_units[unit]++;
422 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
423 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
424 ppc_function_unit first_unit = time_ptr->first_unit;
425 ppc_function_unit second_unit = time_ptr->second_unit;
426 int stall_increment = 0;
429 if (!model_ptr->busy[first_unit])
430 return model_make_busy(model_ptr, first_unit,
431 model_ptr->timing[index].issue,
432 model_ptr->timing[index].done);
434 if (!model_ptr->busy[second_unit])
435 return model_make_busy(model_ptr, second_unit,
436 model_ptr->timing[index].issue,
437 model_ptr->timing[index].done);
439 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
440 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
442 model_new_cycle(model_ptr);
445 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
446 void::model-function::model_serialize:itable_index index, model_data *model_ptr
447 while (model_ptr->busy_head.next) {
448 TRACE(trace_model,("waiting for pipeline to empty\n"));
449 model_ptr->nr_stalls_serialize++;
450 model_new_cycle(model_ptr);
452 (void) model_make_busy(model_ptr,
453 model_ptr->timing[index].first_unit,
454 model_ptr->timing[index].issue,
455 model_ptr->timing[index].done);
457 # Wait for a CR to become unbusy
458 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
462 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
465 cr_mask = (1 << cr_var);
466 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
467 TRACE(trace_model,("waiting for CR %d\n", cr_var));
468 model_ptr->nr_stalls_data++;
469 model_new_cycle(model_ptr);
472 # Schedule an instruction that takes integer input registers and produces output registers
473 void::model-function::ppc_insn_int:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
474 const unsigned32 int_mask = out_mask | in_mask;
475 model_busy *busy_ptr;
477 if ((model_ptr->int_busy & int_mask) != 0) {
478 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
480 while ((model_ptr->int_busy & int_mask) != 0) {
481 if (WITH_TRACE && ppc_trace[trace_model])
482 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
484 model_ptr->nr_stalls_data++;
485 model_new_cycle(model_ptr);
489 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
490 model_ptr->int_busy |= out_mask;
491 busy_ptr->int_busy |= out_mask;
493 busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
495 if (WITH_TRACE && ppc_trace[trace_model])
496 model_trace_make_busy(model_ptr, out_mask, 0, 0);
498 # Schedule an instruction that takes integer input registers and produces output registers & sets a CR register
499 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
500 const unsigned32 int_mask = out_mask | in_mask;
501 model_busy *busy_ptr;
503 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
504 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
506 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
507 if (WITH_TRACE && ppc_trace[trace_model])
508 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
510 model_ptr->nr_stalls_data++;
511 model_new_cycle(model_ptr);
515 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
516 model_ptr->int_busy |= out_mask;
517 busy_ptr->int_busy |= out_mask;
518 model_ptr->cr_fpscr_busy |= cr_mask;
519 busy_ptr->cr_fpscr_busy |= cr_mask;
521 busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
524 busy_ptr->nr_writebacks++;
526 if (WITH_TRACE && ppc_trace[trace_model])
527 model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
530 # Schedule an instruction that takes CR input registers and produces output CR registers
531 void::model-function::ppc_insn_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
532 const unsigned32 cr_mask = out_mask | in_mask;
533 model_busy *busy_ptr;
535 if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
536 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
538 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
539 if (WITH_TRACE && ppc_trace[trace_model])
540 model_trace_busy_p(model_ptr, 0, 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->cr_fpscr_busy |= out_mask;
549 busy_ptr->cr_fpscr_busy |= out_mask;
551 busy_ptr->nr_writebacks = 1;
553 if (WITH_TRACE && ppc_trace[trace_model])
554 model_trace_make_busy(model_ptr, 0, 0, out_mask);
557 # Schedule an instruction that takes floating point input registers and produces an output fp register
558 void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
559 const unsigned32 fp_mask = out_mask | in_mask;
560 model_busy *busy_ptr;
562 if ((model_ptr->fp_busy & fp_mask) != 0) {
563 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
565 while ((model_ptr->fp_busy & fp_mask) != 0) {
566 if (WITH_TRACE && ppc_trace[trace_model])
567 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
569 model_ptr->nr_stalls_data++;
570 model_new_cycle(model_ptr);
574 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
575 model_ptr->fp_busy |= out_mask;
576 busy_ptr->fp_busy |= out_mask;
577 busy_ptr->nr_writebacks = 1;
578 if (WITH_TRACE && ppc_trace[trace_model])
579 model_trace_make_busy(model_ptr, 0, out_mask, 0);
582 # Schedule an instruction that takes floating point input registers and produces an output fp register & sets a CR reg
583 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
584 const unsigned32 fp_mask = out_mask | in_mask;
585 model_busy *busy_ptr;
587 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
588 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
590 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
591 if (WITH_TRACE && ppc_trace[trace_model])
592 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
594 model_ptr->nr_stalls_data++;
595 model_new_cycle(model_ptr);
599 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
600 model_ptr->fp_busy |= out_mask;
601 busy_ptr->fp_busy |= out_mask;
602 model_ptr->cr_fpscr_busy |= cr_mask;
603 busy_ptr->cr_fpscr_busy |= cr_mask;
604 busy_ptr->nr_writebacks = (cr_mask) ? 2 : 1;
605 if (WITH_TRACE && ppc_trace[trace_model])
606 model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
609 # Schedule an instruction that takes both int/float input registers and produces output int/float registers
610 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
611 const unsigned32 int_mask = out_int_mask | in_int_mask;
612 const unsigned32 fp_mask = out_fp_mask | in_fp_mask;
613 model_busy *busy_ptr;
615 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
616 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
618 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
619 if (WITH_TRACE && ppc_trace[trace_model])
620 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
622 model_ptr->nr_stalls_data++;
623 model_new_cycle(model_ptr);
626 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
627 model_ptr->int_busy |= out_int_mask;
628 busy_ptr->int_busy |= out_int_mask;
629 model_ptr->fp_busy |= out_fp_mask;
630 busy_ptr->fp_busy |= out_fp_mask;
631 busy_ptr->nr_writebacks = ((out_int_mask) ? 1 : 0) + ((out_fp_mask) ? 1 : 0);
632 if (WITH_TRACE && ppc_trace[trace_model])
633 model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0);
637 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
638 void::model-function::ppc_insn_from_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
639 model_busy *busy_ptr;
641 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
642 if (WITH_TRACE && ppc_trace[trace_model])
643 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
645 model_ptr->nr_stalls_data++;
646 model_new_cycle(model_ptr);
649 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
650 model_ptr->int_busy |= int_mask;
651 busy_ptr->int_busy |= int_mask;
652 busy_ptr->nr_writebacks = 1;
653 if (WITH_TRACE && ppc_trace[trace_model])
654 model_trace_make_busy(model_ptr, int_mask, 0, 0);
656 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
657 void::model-function::ppc_insn_to_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
658 model_busy *busy_ptr;
660 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
661 if (WITH_TRACE && ppc_trace[trace_model])
662 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
664 model_ptr->nr_stalls_data++;
665 model_new_cycle(model_ptr);
668 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
669 busy_ptr->spr_busy = nSPR;
670 model_ptr->spr_busy[nSPR] = 1;
671 busy_ptr->nr_writebacks = 1;
672 TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));
674 # Schedule a MFCR instruction that moves the CR into an integer regsiter
675 void::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, unsigned32 int_mask
676 const unsigned32 cr_mask = 0xff;
677 model_busy *busy_ptr;
679 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
680 if (WITH_TRACE && ppc_trace[trace_model])
681 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
683 model_ptr->nr_stalls_data++;
684 model_new_cycle(model_ptr);
687 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
688 model_ptr->int_busy |= int_mask;
689 busy_ptr->int_busy |= int_mask;
690 busy_ptr->nr_writebacks = 1;
691 if (WITH_TRACE && ppc_trace[trace_model])
692 model_trace_make_busy(model_ptr, int_mask, 0, 0);
694 # Schedule a MTCR instruction that moves an integer register into the CR
695 void::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, unsigned32 int_mask, unsigned FXM
698 unsigned32 cr_mask = 0;
699 const model_time *normal_time = &model_ptr->timing[index];
700 static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 };
701 model_busy *busy_ptr;
703 for (f = 0; f < 8; f++) {
704 if (FXM & (0x80 >> f)) {
710 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
711 if (WITH_TRACE && ppc_trace[trace_model])
712 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
714 model_ptr->nr_stalls_data++;
715 model_new_cycle(model_ptr);
718 /* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */
719 if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) {
720 normal_time = &ppc604_1bit_time;
723 busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
724 busy_ptr->cr_fpscr_busy |= cr_mask;
725 model_ptr->cr_fpscr_busy |= cr_mask;
726 model_ptr->nr_mtcrf_crs[nr_crs]++;
727 busy_ptr->nr_writebacks = 1;
728 if (WITH_TRACE && ppc_trace[trace_model])
729 model_trace_make_busy(model_ptr, 0, 0, cr_mask);
731 model_data *::model-function::model_create:cpu *processor
732 model_data *model_ptr = ZALLOC(model_data);
733 model_ptr->name = model_name[CURRENT_MODEL];
734 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
735 model_ptr->processor = processor;
736 model_ptr->nr_cycles = 1;
737 model_ptr->busy_tail = &model_ptr->busy_head;
738 switch (CURRENT_MODEL) {
739 case MODEL_ppc601: model_ptr->max_nr_writebacks = 1; break; /* ??? */
740 case MODEL_ppc603: model_ptr->max_nr_writebacks = 2; break;
741 case MODEL_ppc603e: model_ptr->max_nr_writebacks = 2; break;
742 case MODEL_ppc604: model_ptr->max_nr_writebacks = 2; break;
743 default: error ("Unknown model %d\n", CURRENT_MODEL);
747 void::model-function::model_init:model_data *model_ptr
749 void::model-function::model_halt:model_data *model_ptr
750 /* Let pipeline drain */
751 while (model_ptr->busy_head.next)
752 model_new_cycle(model_ptr);
754 unsigned_word::model-function::model_get_number_of_stalls:model_data *model_ptr
755 return (model_ptr->nr_stalls_data
756 + model_ptr->nr_stalls_unit
757 + model_ptr->nr_stalls_serialize
758 + model_ptr->nr_stalls_writeback);
760 unsigned_word::model-function::model_get_number_of_cycles:model_data *model_ptr
761 return (model_ptr->nr_cycles);
763 model_print *::model-function::model_mon_info:model_data *model_ptr
770 head = tail = ZALLOC(model_print);
771 tail->count = model_ptr->nr_cycles;
772 tail->name = "cycle";
773 tail->suffix_plural = "s";
774 tail->suffix_singular = "";
776 if (model_ptr->nr_stalls_data) {
777 tail->next = ZALLOC(model_print);
779 tail->count = model_ptr->nr_stalls_data;
780 tail->name = "stall";
781 tail->suffix_plural = "s waiting for data";
782 tail->suffix_singular = " waiting for data";
785 if (model_ptr->nr_stalls_unit) {
786 tail->next = ZALLOC(model_print);
788 tail->count = model_ptr->nr_stalls_unit;
789 tail->name = "stall";
790 tail->suffix_plural = "s waiting for a function unit";
791 tail->suffix_singular = " waiting for a function unit";
794 if (model_ptr->nr_stalls_serialize) {
795 tail->next = ZALLOC(model_print);
797 tail->count = model_ptr->nr_stalls_serialize;
798 tail->name = "stall";
799 tail->suffix_plural = "s waiting for serialization";
800 tail->suffix_singular = " waiting for serialization";
803 if (model_ptr->nr_stalls_writeback) {
804 tail->next = ZALLOC(model_print);
806 tail->count = model_ptr->nr_stalls_writeback;
808 tail->suffix_plural = "times a write-back slot was unavailable";
809 tail->suffix_singular = "time a writeback was unavilable";
812 if (model_ptr->nr_branches) {
813 tail->next = ZALLOC(model_print);
815 tail->count = model_ptr->nr_branches;
816 tail->name = "branch";
817 tail->suffix_plural = "es";
818 tail->suffix_singular = "";
821 if (model_ptr->nr_branches_fallthrough) {
822 tail->next = ZALLOC(model_print);
824 tail->count = model_ptr->nr_branches_fallthrough;
825 tail->name = "conditional branch";
826 tail->suffix_plural = "es fell through";
827 tail->suffix_singular = " fell through";
830 if (model_ptr->nr_branch_predict_trues) {
831 tail->next = ZALLOC(model_print);
833 tail->count = model_ptr->nr_branch_predict_trues;
834 tail->name = "successful branch prediction";
835 tail->suffix_plural = "s";
836 tail->suffix_singular = "";
839 if (model_ptr->nr_branch_predict_falses) {
840 tail->next = ZALLOC(model_print);
842 tail->count = model_ptr->nr_branch_predict_falses;
843 tail->name = "unsuccessful branch prediction";
844 tail->suffix_plural = "s";
845 tail->suffix_singular = "";
848 for (j = 0; j < (sizeof(ppc_branch_conditional_name) / sizeof(ppc_branch_conditional_name[0])) ; j++) {
849 if (model_ptr->nr_branch_conditional[j]) {
850 tail->next = ZALLOC(model_print);
852 tail->count = model_ptr->nr_branch_conditional[j];
853 tail->name = ppc_branch_conditional_name[j];
854 tail->suffix_plural = " conditional branches";
855 tail->suffix_singular = " conditional branch";
859 for (j = 0; j < 9; j++) {
860 if (model_ptr->nr_mtcrf_crs[j]) {
861 tail->next = ZALLOC(model_print);
863 tail->count = model_ptr->nr_mtcrf_crs[j];
864 tail->name = ppc_nr_mtcrf_crs[j];
865 tail->suffix_plural = " instructions";
866 tail->suffix_singular = " instruction";
871 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
872 if (model_ptr->nr_units[i]) {
873 nr_insns += model_ptr->nr_units[i];
874 tail->next = ZALLOC(model_print);
876 tail->count = model_ptr->nr_units[i];
877 tail->name = ppc_function_unit_name[i];
878 tail->suffix_plural = "s";
879 tail->suffix_singular = "";
883 tail->next = ZALLOC(model_print);
885 tail->count = nr_insns;
886 tail->name = "instruction";
887 tail->suffix_plural = "s that were accounted for in timing info";
888 tail->suffix_singular = " that was accounted for in timing info";
890 tail->next = (model_print *)0;
893 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
895 model_print *next = ptr->next;
900 void::model-function::model_branches:model_data *model_ptr, int failed, int conditional
901 model_ptr->nr_units[PPC_UNIT_BPU]++;
903 model_ptr->nr_branches_fallthrough++;
905 model_ptr->nr_branches++;
906 if (conditional >= 0)
907 model_ptr->nr_branch_conditional[conditional]++;
908 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
910 void::model-function::model_branch_predict:model_data *model_ptr, int success
912 model_ptr->nr_branch_predict_trues++;
914 model_ptr->nr_branch_predict_falses++;
917 # The following (illegal) instruction is `known' by gen and is
918 # called when ever an illegal instruction is encountered
920 program_interrupt(processor, cia,
921 illegal_instruction_program_interrupt);
924 # The following (floating point unavailable) instruction is `known' by gen
925 # and is called when ever an a floating point instruction is to be
926 # executed but floating point is make unavailable by the MSR
927 ::internal::floating_point_unavailable
928 floating_point_unavailable_interrupt(processor, cia);
932 # Floating point support functions
935 # Convert 32bit single to 64bit double
936 unsigned64::function::DOUBLE:unsigned32 WORD
938 if (EXTRACTED32(WORD, 1, 8) > 0
939 && EXTRACTED32(WORD, 1, 8) < 255) {
940 /* normalized operand */
941 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
942 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
943 | INSERTED64(not_word_1_1, 2, 2)
944 | INSERTED64(not_word_1_1, 3, 3)
945 | INSERTED64(not_word_1_1, 4, 4)
946 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
948 else if (EXTRACTED32(WORD, 1, 8) == 0
949 && EXTRACTED32(WORD, 9, 31) != 0) {
950 /* denormalized operand */
951 int sign = EXTRACTED32(WORD, 0, 0);
953 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
954 /* normalize the operand */
955 while (MASKED64(frac, 0, 0) == 0) {
959 FRT = (INSERTED64(sign, 0, 0)
960 | INSERTED64(exp + 1023, 1, 11)
961 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
963 else if (EXTRACTED32(WORD, 1, 8) == 255
964 || EXTRACTED32(WORD, 1, 31) == 0) {
965 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
966 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
967 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
968 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
969 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
972 error("DOUBLE - unknown case\n");
977 # Convert 64bit single to 32bit double
978 unsigned32::function::SINGLE:unsigned64 FRS
980 if (EXTRACTED64(FRS, 1, 11) > 896
981 || EXTRACTED64(FRS, 1, 63) == 0) {
982 /* no denormalization required (includes Zero/Infinity/NaN) */
983 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
984 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
986 else if (874 <= EXTRACTED64(FRS, 1, 11)
987 && EXTRACTED64(FRS, 1, 11) <= 896) {
988 /* denormalization required */
989 int sign = EXTRACTED64(FRS, 0, 0);
990 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
991 unsigned64 frac = (BIT64(0)
992 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
993 /* denormalize the operand */
995 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
998 WORD = (INSERTED32(sign, 0, 0)
999 | INSERTED32(0x00, 1, 8)
1000 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
1003 WORD = 0x0; /* ??? */
1008 # round 64bit double to 64bit but single
1009 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
1010 /* comparisons ignore u bits */
1013 int lsb = EXTRACTED64(*frac_grx, 23, 23);
1014 int gbit = EXTRACTED64(*frac_grx, 24, 24);
1015 int rbit = EXTRACTED64(*frac_grx, 25, 25);
1016 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
1017 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
1018 if (lsb == 1 && gbit == 1) inc = 1;
1019 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1020 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1022 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
1023 if (sign == 0 && gbit == 1) inc = 1;
1024 if (sign == 0 && rbit == 1) inc = 1;
1025 if (sign == 0 && xbit == 1) inc = 1;
1027 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
1028 if (sign == 1 && gbit == 1) inc = 1;
1029 if (sign == 1 && rbit == 1) inc = 1;
1030 if (sign == 1 && xbit == 1) inc = 1;
1032 /* work out addition in low 25 bits of out */
1033 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
1034 *frac_grx = INSERTED64(out, 0, 23);
1035 if (out & BIT64(64 - 23 - 1 - 1)) {
1036 *frac_grx = (BIT64(0) |
1037 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
1040 /* frac_grx[24:52] = 0 already */
1042 FPSCR_SET_FI(gbit || rbit || xbit);
1046 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
1048 if (round_mode == fpscr_rn_round_to_nearest) {
1049 if (*frac64 == 1 && gbit == 1) inc = 1;
1050 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
1051 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
1053 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1054 if (sign == 0 && gbit == 1) inc = 1;
1055 if (sign == 0 && rbit == 1) inc = 1;
1056 if (sign == 0 && xbit == 1) inc = 1;
1058 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1059 if (sign == 1 && gbit == 1) inc = 1;
1060 if (sign == 1 && rbit == 1) inc = 1;
1061 if (sign == 1 && xbit == 1) inc = 1;
1063 /* frac[0:64] = frac[0:64} + inc */
1064 *frac += (*frac64 && inc ? 1 : 0);
1065 *frac64 = (*frac64 + inc) & 0x1;
1067 FPSCR_SET_FI(gbit | rbit | xbit);
1070 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
1073 int lsb = EXTRACTED64(*frac, 52, 52);
1074 int gbit = EXTRACTED64(*frac, 53, 53);
1075 int rbit = EXTRACTED64(*frac, 54, 54);
1076 int xbit = EXTRACTED64(*frac, 55, 55);
1077 if (round_mode == fpscr_rn_round_to_nearest) {
1078 if (lsb == 1 && gbit == 1) inc = 1;
1079 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1080 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1082 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1083 if (sign == 0 && gbit == 1) inc = 1;
1084 if (sign == 0 && rbit == 1) inc = 1;
1085 if (sign == 0 && xbit == 1) inc = 1;
1087 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1088 if (sign == 1 && gbit == 1) inc = 1;
1089 if (sign == 1 && rbit == 1) inc = 1;
1090 if (sign == 1 && xbit == 1) inc = 1;
1092 /* frac//carry_out = frac + inc */
1093 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1094 carry_out = EXTRACTED64(*frac, 0, 0);
1096 if (carry_out == 1) *exp = *exp + 1;
1098 FPSCR_SET_FI(gbit | rbit | xbit);
1099 FPSCR_SET_XX(FPSCR & fpscr_fi);
1102 # conversion of FP to integer
1103 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
1106 unsigned64 frac = 0;
1111 int sign = EXTRACTED64(frb, 0, 0);
1112 enum { start, finish, Infinity_Operand, SNaN_Operand, QNaN_Operand, Large_Operand, Done } label = start;
1113 while (label != finish) switch (label) {
1115 error("Unhandled switch\n");
1117 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1118 { label = Infinity_Operand; break; }
1119 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1120 { label = SNaN_Operand; break; }
1121 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1122 { label = QNaN_Operand; break; }
1123 if (EXTRACTED64(frb, 1, 11) > 1086) { label = Large_Operand; break; }
1124 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1125 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1126 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1127 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1130 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1131 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1134 gbit = 0, rbit = 0, xbit = 0;
1135 for (i = 1; i <= 63 - exp; i++) {
1139 frac64 = EXTRACTED64(frac, 63, 63);
1140 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1142 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1143 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1146 frac += (frac64 ? 1 : 0);
1147 frac64 = (frac64 + 1) & 0x1;
1149 if (tgt_precision == 32 /* can ignore frac64 in compare */
1150 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1151 { label = Large_Operand; break; }
1152 if (tgt_precision == 64 /* can ignore frac64 in compare */
1153 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1154 { label = Large_Operand; break; }
1155 if (tgt_precision == 32 /* can ignore frac64 in compare */
1156 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1157 { label = Large_Operand; break; }
1158 if (tgt_precision == 64 /* can ignore frac64 in compare */
1159 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1160 { label = Large_Operand; break; }
1161 FPSCR_SET_XX(FPSCR & fpscr_fi);
1162 if (tgt_precision == 32)
1163 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1164 if (tgt_precision == 64)
1165 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1166 /*FPSCR[fprf] = undefined */
1167 { label = Done; break; }
1169 case Infinity_Operand:
1172 FPSCR_OR_VX(fpscr_vxcvi);
1173 if ((FPSCR & fpscr_ve) == 0) {
1174 if (tgt_precision == 32) {
1175 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1176 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1179 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1180 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1182 /* FPSCR[FPRF] = undefined */
1184 { label = Done; break; }
1189 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1190 if ((FPSCR & fpscr_ve) == 0) {
1191 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1192 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1193 /* FPSCR[fprf] = undefined */
1195 { label = Done; break; }
1200 FPSCR_OR_VX(fpscr_vxcvi);
1201 if ((FPSCR & fpscr_ve) == 0) {
1202 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1203 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1204 /* FPSCR[fprf] = undefined */
1206 { label = Done; break; }
1211 FPSCR_OR_VX(fpscr_vxcvi);
1212 if ((FPSCR & fpscr_ve) == 0) {
1213 if (tgt_precision == 32) {
1214 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1215 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1218 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1219 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1221 /* FPSCR[fprf] = undefined */
1225 { label = finish; break; }
1229 # extract out raw fields of a FP number
1230 int::function::sign:unsigned64 FRS
1231 return (MASKED64(FRS, 0, 0)
1234 int::function::biased_exp:unsigned64 frs, int single
1236 return EXTRACTED64(frs, 1, 8);
1238 return EXTRACTED64(frs, 1, 11);
1239 unsigned64::function::fraction:unsigned64 frs, int single
1241 return EXTRACTED64(frs, 9, 31);
1243 return EXTRACTED64(frs, 12, 63);
1245 # a number?, each of the below return +1 or -1 (based on sign bit)
1247 int::function::is_nor:unsigned64 frs, int single
1248 int exp = biased_exp(frs, single);
1250 && exp <= (single ? 254 : 2046));
1251 int::function::is_zero:unsigned64 FRS
1252 return (MASKED64(FRS, 1, 63) == 0
1255 int::function::is_den:unsigned64 frs, int single
1256 int exp = biased_exp(frs, single);
1257 unsigned64 frac = fraction(frs, single);
1258 return (exp == 0 && frac != 0
1261 int::function::is_inf:unsigned64 frs, int single
1262 int exp = biased_exp(frs, single);
1263 int frac = fraction(frs, single);
1264 return (exp == (single ? 255 : 2047) && frac == 0
1267 int::function::is_NaN:unsigned64 frs, int single
1268 int exp = biased_exp(frs, single);
1269 int frac = fraction(frs, single);
1270 return (exp == (single ? 255 : 2047) && frac != 0
1273 int::function::is_SNaN:unsigned64 frs, int single
1274 return (is_NaN(frs, single)
1275 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1278 int::function::is_QNaN:unsigned64 frs, int single
1279 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1280 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1281 return *(double*)fra < *(double*)frb;
1282 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1283 return *(double*)fra > *(double*)frb;
1284 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1285 return *(double*)fra == *(double*)frb;
1288 # which quiet nan should become the result
1289 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1291 if (is_NaN(fra, single))
1293 else if (is_NaN(frb, single))
1294 if (instruction_is_frsp)
1295 frt = MASKED64(frb, 0, 34);
1298 else if (is_NaN(frc, single))
1300 else if (generate_qnan)
1301 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1303 error("select_qnan - default reached\n");
1307 # detect invalid operation
1308 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1310 if ((check & fpscr_vxsnan)
1311 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1312 FPSCR_OR_VX(fpscr_vxsnan);
1315 if ((check & fpscr_vxisi)
1316 && (is_inf(fra, single) && is_inf(frb, single))
1317 && ((negate && sign(fra) != sign(frb))
1318 || (!negate && sign(fra) == sign(frb)))) {
1319 /*FIXME: don't handle inf-inf VS inf+-inf */
1320 FPSCR_OR_VX(fpscr_vxisi);
1323 if ((check & fpscr_vxidi)
1324 && (is_inf(fra, single) && is_inf(frb, single))) {
1325 FPSCR_OR_VX(fpscr_vxidi);
1328 if ((check & fpscr_vxzdz)
1329 && (is_zero(fra) && is_zero(frb))) {
1330 FPSCR_OR_VX(fpscr_vxzdz);
1333 if ((check & fpscr_vximz)
1334 && (is_zero(fra) && is_inf(frb, single))) {
1335 FPSCR_OR_VX(fpscr_vximz);
1338 if ((check & fpscr_vxvc)
1339 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1340 FPSCR_OR_VX(fpscr_vxvc);
1343 if ((check & fpscr_vxsoft)) {
1344 FPSCR_OR_VX(fpscr_vxsoft);
1347 if ((check & fpscr_vxsqrt)
1349 FPSCR_OR_VX(fpscr_vxsqrt);
1352 /* if ((check && fpscr_vxcvi) {
1353 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1354 FPSCR_OR_VX(fpscr_vxcvi);
1364 # handle case of invalid operation
1365 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
1366 if (FPSCR & fpscr_ve) {
1367 /* invalid operation exception enabled */
1371 /* fpscr_FPRF unchanged */
1374 /* invalid operation exception disabled */
1375 if (instruction_is_convert_to_64bit) {
1378 else if (instruction_is_convert_to_32bit) {
1381 else { /* arrith, frsp */
1382 *frt = select_qnan(fra, frb, frc,
1383 instruction_is_frsp, 0/*generate*/, single);
1386 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1394 # 0.0.0.0 Illegal instruction used for kernel mode emulation
1396 0.0,6./,11./,16./,21./,31.1:X:::instruction_call
1397 if (!os_emul_instruction_call(processor, cia, real_addr(cia, 1)))
1398 program_interrupt(processor, cia,
1399 illegal_instruction_program_interrupt);
1402 # I.2.4.1 Branch Instructions
1404 0.18,6.LI,30.AA,31.LK:I:::Branch
1405 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1406 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1407 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1408 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1409 if (AA) NIA = IEA(EXTS(LI_0b00));
1410 else NIA = IEA(CIA + EXTS(LI_0b00));
1411 if (LK) LR = (spreg)CIA+4;
1412 if (CURRENT_MODEL_ISSUE > 0)
1413 model_branches(cpu_model(processor), 1, -1);
1415 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:::Branch Conditional
1416 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1417 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1418 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1419 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1420 int M, ctr_ok, cond_ok, succeed;
1421 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1422 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1423 if (is_64bit_implementation && is_64bit_mode) M = 0;
1425 if (!BO{2}) CTR = CTR - 1;
1426 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1427 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1428 if (ctr_ok && cond_ok) {
1429 if (AA) NIA = IEA(EXTS(BD_0b00));
1430 else NIA = IEA(CIA + EXTS(BD_0b00));
1435 if (LK) LR = (spreg)IEA(CIA + 4);
1436 if (CURRENT_MODEL_ISSUE > 0)
1437 model_branches(cpu_model(processor), succeed, BO);
1440 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1441 reverse = EXTS(BD_0b00) < 0;
1442 } else { /* branch prediction bit not set */
1443 reverse = EXTS(BD_0b00) >= 0;
1445 if (CURRENT_MODEL_ISSUE > 0)
1446 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1449 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:::Branch Conditional to Link Register
1450 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1451 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1452 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1453 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1454 int M, ctr_ok, cond_ok, succeed;
1455 if (is_64bit_implementation && is_64bit_mode) M = 0;
1457 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1458 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1459 if (!BO{2}) CTR = CTR - 1;
1460 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1461 cond_ok = BO{0} || (CR{BI} == BO{1});
1462 if (ctr_ok && cond_ok) {
1468 if (LK) LR = (spreg)IEA(CIA + 4);
1469 if (CURRENT_MODEL_ISSUE > 0) {
1470 model_branches(cpu_model(processor), succeed, BO);
1472 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1475 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:::Branch Conditional to Count Register
1476 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1477 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1478 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1479 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1480 int cond_ok, succeed;
1481 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1482 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1483 cond_ok = BO{0} || (CR{BI} == BO{1});
1485 NIA = IEA(CTR_0b00);
1490 if (LK) LR = (spreg)IEA(CIA + 4);
1491 if (CURRENT_MODEL_ISSUE > 0) {
1492 model_branches(cpu_model(processor), succeed, BO);
1494 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1498 # I.2.4.2 System Call Instruction
1500 0.17,6./,11./,16./,30.1,31./:SC:::System Call
1501 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1502 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1503 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1504 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1505 if (CURRENT_MODEL_ISSUE > 0)
1506 model_serialize(MY_INDEX, cpu_model(processor));
1507 system_call_interrupt(processor, cia);
1510 # I.2.4.3 Condition Register Logical Instructions
1512 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1513 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1514 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1515 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1516 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1517 BLIT32(CR, BT, CR{BA} && CR{BB});
1518 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1520 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1521 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1522 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1523 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1524 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1525 BLIT32(CR, BT, CR{BA} || CR{BB});
1526 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1528 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1529 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1530 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1531 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1532 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1533 BLIT32(CR, BT, CR{BA} != CR{BB});
1534 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1536 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1537 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1538 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1539 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1540 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1541 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1542 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1544 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1545 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1546 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1547 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1548 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1549 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1550 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1552 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1553 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1554 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1555 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1556 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1557 BLIT32(CR, BT, CR{BA} == CR{BB});
1558 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1560 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1561 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1562 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1563 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1564 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1565 BLIT32(CR, BT, CR{BA} && !CR{BB});
1566 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1568 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1569 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1570 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1571 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1572 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1573 BLIT32(CR, BT, CR{BA} || !CR{BB});
1574 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1577 # I.2.4.4 Condition Register Field Instruction
1579 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1580 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1581 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1582 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1583 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1584 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1585 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
1589 # I.3.3.2 Fixed-Point Load Instructions
1592 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1593 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1594 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1595 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1596 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1602 *rT = MEM(unsigned, EA, 1);
1603 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1606 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1607 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1608 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1609 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1610 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1616 *rT = MEM(unsigned, EA, 1);
1617 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1619 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1620 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1621 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1622 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1623 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1625 if (RA == 0 || RA == RT)
1626 program_interrupt(processor, cia,
1627 illegal_instruction_program_interrupt);
1629 *rT = MEM(unsigned, EA, 1);
1631 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1633 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1634 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1635 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1636 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1637 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1639 if (RA == 0 || RA == RT)
1640 program_interrupt(processor, cia,
1641 illegal_instruction_program_interrupt);
1643 *rT = MEM(unsigned, EA, 1);
1645 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1647 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1648 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1649 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1650 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1651 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1657 *rT = MEM(unsigned, EA, 2);
1658 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1660 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1661 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1662 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1663 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1664 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1670 *rT = MEM(unsigned, EA, 2);
1671 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1673 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1674 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1675 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1676 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1677 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1679 if (RA == 0 || RA == RT)
1680 program_interrupt(processor, cia,
1681 illegal_instruction_program_interrupt);
1683 *rT = MEM(unsigned, EA, 2);
1685 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1687 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1688 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1689 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1690 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1691 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1693 if (RA == 0 || RA == RT)
1694 program_interrupt(processor, cia,
1695 illegal_instruction_program_interrupt);
1697 *rT = MEM(unsigned, EA, 2);
1699 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1701 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1702 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1703 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1704 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1705 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1711 *rT = MEM(signed, EA, 2);
1712 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1714 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1715 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1716 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1717 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1718 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1724 *rT = MEM(signed, EA, 2);
1725 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1727 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1728 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1729 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1730 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1731 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1733 if (RA == 0 || RA == RT)
1734 program_interrupt(processor, cia,
1735 illegal_instruction_program_interrupt);
1737 *rT = MEM(signed, EA, 2);
1738 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1740 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1741 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1742 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1743 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1744 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1746 if (RA == 0 || RA == RT)
1747 program_interrupt(processor, cia,
1748 illegal_instruction_program_interrupt);
1750 *rT = MEM(signed, EA, 2);
1752 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1754 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1755 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1756 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1757 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1758 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1764 *rT = MEM(unsigned, EA, 4);
1765 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1767 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1768 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1769 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1770 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1771 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1777 *rT = MEM(unsigned, EA, 4);
1778 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1780 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1781 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1782 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1783 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1784 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1786 if (RA == 0 || RA == RT)
1787 program_interrupt(processor, cia,
1788 illegal_instruction_program_interrupt);
1790 *rT = MEM(unsigned, EA, 4);
1792 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1794 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1795 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1796 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1797 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1798 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1800 if (RA == 0 || RA == RT)
1801 program_interrupt(processor, cia,
1802 illegal_instruction_program_interrupt);
1804 *rT = MEM(unsigned, EA, 4);
1806 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1808 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1811 # if (RA == 0) b = 0;
1813 # EA = b + EXTS(DS_0b00);
1814 # *rT = MEM(signed, EA, 4);
1816 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1819 # if (RA == 0) b = 0;
1822 # *rT = MEM(signed, EA, 4);
1824 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1826 # if (RA == 0 || RA == RT)
1827 # program_interrupt(processor, cia
1828 # illegal_instruction_program_interrupt);
1830 # *rT = MEM(signed, EA, 4);
1833 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1836 # if (RA == 0) b = 0;
1838 # EA = b + EXTS(DS_0b00);
1839 # *rT = MEM(unsigned, EA, 8);
1841 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1844 # if (RA == 0) b = 0;
1847 # *rT = MEM(unsigned, EA, 8);
1849 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1851 # if (RA == 0 || RA == RT)
1852 # program_interrupt(processor, cia
1853 # illegal_instruction_program_interrupt);
1854 # EA = *rA + EXTS(DS_0b00);
1855 # *rT = MEM(unsigned, EA, 8);
1858 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1860 # if (RA == 0 || RA == RT)
1861 # program_interrupt(processor, cia
1862 # illegal_instruction_program_interrupt);
1864 # *rT = MEM(unsigned, EA, 8);
1870 # I.3.3.3 Fixed-Point Store Instructions
1873 0.38,6.RS,11.RA,16.D:D:::Store Byte
1874 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1875 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1876 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1877 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1884 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1886 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1887 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1888 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1889 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1890 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1897 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1899 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1900 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1901 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1902 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1903 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1906 program_interrupt(processor, cia,
1907 illegal_instruction_program_interrupt);
1911 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1913 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1914 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1915 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1916 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1917 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1920 program_interrupt(processor, cia,
1921 illegal_instruction_program_interrupt);
1925 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1927 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1928 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1929 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1930 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1931 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1938 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1940 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1941 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1942 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1943 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1944 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1951 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1953 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1954 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1955 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1956 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1957 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1960 program_interrupt(processor, cia,
1961 illegal_instruction_program_interrupt);
1965 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1967 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1968 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1969 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1970 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1971 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1974 program_interrupt(processor, cia,
1975 illegal_instruction_program_interrupt);
1979 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1981 0.36,6.RS,11.RA,16.D:D:::Store Word
1982 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1983 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1984 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1985 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1992 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1994 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
1995 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1996 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1997 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1998 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2005 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2007 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
2008 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2009 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2010 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2011 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2014 program_interrupt(processor, cia,
2015 illegal_instruction_program_interrupt);
2019 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2021 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
2022 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2023 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2024 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2025 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2028 program_interrupt(processor, cia,
2029 illegal_instruction_program_interrupt);
2033 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2035 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2038 # if (RA == 0) b = 0;
2040 # EA = b + EXTS(DS_0b00);
2041 # STORE(EA, 8, *rS);
2042 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2045 # if (RA == 0) b = 0;
2048 # STORE(EA, 8, *rS);
2049 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2052 # program_interrupt(processor, cia
2053 # illegal_instruction_program_interrupt);
2054 # EA = *rA + EXTS(DS_0b00);
2055 # STORE(EA, 8, *rS);
2057 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2060 # program_interrupt(processor, cia
2061 # illegal_instruction_program_interrupt);
2063 # STORE(EA, 8, *rS);
2068 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2071 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2072 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2073 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2074 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2075 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2081 *rT = SWAP_2(MEM(unsigned, EA, 2));
2082 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2084 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2085 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2086 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2087 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2088 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2094 *rT = SWAP_4(MEM(unsigned, EA, 4));
2095 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2097 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2098 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2099 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2100 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2101 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2107 STORE(EA, 2, SWAP_2(*rS));
2108 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2110 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2111 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2112 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2113 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2114 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2120 STORE(EA, 4, SWAP_4(*rS));
2121 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2125 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2128 0.46,6.RT,11.RA,16.D:D:::Load Multiple Word
2130 0.47,6.RS,11.RA,16.D:D:::Store Multiple Word
2134 # I.3.3.6 Fixed-Point Move Assist Instructions
2137 0.31,6.RT,11.RA,16.NB,21.597,31./:X:::Load String Word Immediate
2139 0.31,6.RT,11.RA,16.RB,21.533,31./:X:::Load String Word Indexed
2141 0.31,6.RS,11.RA,16.NB,21.725,31./:X:::Store String Word Immedate
2143 0.31,6.RS,11.RA,16.RB,21.661,31./:X:::Store String Word Indexed
2147 # I.3.3.7 Storage Synchronization Instructions
2149 # HACK: Rather than monitor addresses looking for a reason
2150 # to cancel a reservation. This code instead keeps
2151 # a copy of the data read from memory. Before performing
2152 # a store, the memory area is checked to see if it has
2154 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2155 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2156 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2157 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2158 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2165 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2166 RESERVE_DATA = MEM(unsigned, EA, 4);
2168 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2170 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2177 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2178 RESERVE_DATA = MEM(unsigned, EA, 8);
2180 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2182 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2183 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2184 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2185 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2186 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2193 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2194 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2196 CR_SET_XER_SO(0, cr_i_zero);
2199 /* ment to randomly to store, we never do! */
2200 CR_SET_XER_SO(0, 0);
2205 CR_SET_XER_SO(0, 0);
2207 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2209 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2216 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2217 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2219 CR_SET_XER_SO(0, cr_i_zero);
2222 /* ment to randomly to store, we never do */
2223 CR_SET_XER_SO(0, 0);
2228 CR_SET_XER_SO(0, 0);
2230 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2232 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2233 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2234 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2235 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2236 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2241 # I.3.3.9 Fixed-Point Arithmetic Instructions
2244 0.14,6.RT,11.RA,16.SI:D:::Add Immediate
2245 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2246 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2247 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2248 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2249 if (RA_is_0) *rT = EXTS(SI);
2250 else *rT = *rA + EXTS(SI);
2251 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2252 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2254 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2255 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2256 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2257 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2258 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2259 if (RA_is_0) *rT = EXTS(SI) << 16;
2260 else *rT = *rA + (EXTS(SI) << 16);
2261 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2262 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2264 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2265 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2266 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2267 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2268 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2271 ALU_END(*rT, 0/*CA*/, OE, Rc);
2272 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2274 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2275 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2276 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2277 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2278 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2283 ALU_END(*rT, 0/*CA*/, OE, Rc);
2284 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2286 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2287 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2288 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2289 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2290 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2293 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2294 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2296 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2297 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2298 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2299 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2300 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2303 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2304 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
2306 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2307 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2308 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2309 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2310 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2315 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2316 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2318 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2319 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2320 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2321 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2322 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2325 ALU_END(*rT, 1/*CA*/, OE, Rc);
2326 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2328 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2329 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2330 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2331 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2332 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2333 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2338 ALU_END(*rT, 1/*CA*/, OE, Rc);
2339 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2341 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2342 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2343 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2344 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2345 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2349 ALU_END(*rT, 1/*CA*/, OE, Rc);
2350 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2352 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2353 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2354 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2355 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2356 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2361 ALU_END(*rT, 1/*CA*/, OE, Rc);
2362 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2364 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2365 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2366 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2367 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2368 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2372 ALU_END(*rT, 1/*CA*/, OE, Rc);
2373 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2375 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2376 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2377 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2378 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2379 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2384 ALU_END(*rT, 1/*CA*/, OE, Rc);
2385 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2387 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2388 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2389 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2390 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2391 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2394 ALU_END(*rT, 1/*CA*/, OE, Rc);
2395 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2397 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2398 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2399 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2400 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2401 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2405 ALU_END(*rT, 1/*CA*/, OE, Rc);
2406 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2408 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2409 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2410 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2411 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2412 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2416 ALU_END(*rT,0/*CA*/,OE,Rc);
2417 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2419 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2420 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2421 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2422 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2423 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2424 signed_word prod = *rA * EXTS(SI);
2426 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2428 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2430 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2431 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2432 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2433 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2434 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2435 signed64 a = (signed32)(*rA);
2436 signed64 b = (signed32)(*rB);
2437 signed64 prod = a * b;
2438 signed_word t = prod;
2440 if (t != prod && OE)
2441 XER |= (xer_overflow | xer_summary_overflow);
2442 CR0_COMPARE(t, 0, Rc);
2443 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2445 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2447 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2448 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2449 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2450 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2451 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2452 signed64 a = (signed32)(*rA);
2453 signed64 b = (signed32)(*rB);
2454 signed64 prod = a * b;
2455 signed_word t = EXTRACTED64(prod, 0, 31);
2457 CR0_COMPARE(t, 0, Rc);
2458 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2460 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2462 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2463 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2464 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2465 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2466 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2467 unsigned64 a = (unsigned32)(*rA);
2468 unsigned64 b = (unsigned32)(*rB);
2469 unsigned64 prod = a * b;
2470 signed_word t = EXTRACTED64(prod, 0, 31);
2472 CR0_COMPARE(t, 0, Rc);
2473 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2475 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2477 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2478 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2479 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2480 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2481 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2482 signed64 dividend = (signed32)(*rA);
2483 signed64 divisor = (signed32)(*rB);
2484 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2485 || (dividend == 0x80000000 && divisor == -1)) {
2487 XER |= (xer_overflow | xer_summary_overflow);
2488 CR0_COMPARE(0, 0, Rc);
2491 signed64 quotent = dividend / divisor;
2493 CR0_COMPARE((signed_word)quotent, 0, Rc);
2495 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2497 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2499 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2500 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2501 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2502 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2503 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2504 unsigned64 dividend = (unsigned32)(*rA);
2505 unsigned64 divisor = (unsigned32)(*rB);
2508 XER |= (xer_overflow | xer_summary_overflow);
2509 CR0_COMPARE(0, 0, Rc);
2512 unsigned64 quotent = dividend / divisor;
2514 CR0_COMPARE((signed_word)quotent, 0, Rc);
2516 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2520 # I.3.3.10 Fixed-Point Compare Instructions
2523 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2524 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2525 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2526 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2527 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2528 if (!is_64bit_mode && L)
2529 program_interrupt(processor, cia,
2530 illegal_instruction_program_interrupt);
2533 signed_word b = EXTS(SI);
2538 CR_COMPARE(BF, a, b);
2540 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2542 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2543 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2544 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2545 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2546 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2547 if (!is_64bit_mode && L)
2548 program_interrupt(processor, cia,
2549 illegal_instruction_program_interrupt);
2561 CR_COMPARE(BF, a, b);
2563 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2565 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2566 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2567 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2568 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2569 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2570 if (!is_64bit_mode && L)
2571 program_interrupt(processor, cia,
2572 illegal_instruction_program_interrupt);
2575 unsigned_word b = UI;
2577 a = MASKED(*rA, 32, 63);
2580 CR_COMPARE(BF, a, b);
2582 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2584 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2585 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2586 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2587 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2588 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2589 if (!is_64bit_mode && L)
2590 program_interrupt(processor, cia,
2591 illegal_instruction_program_interrupt);
2596 a = MASKED(*rA, 32, 63);
2597 b = MASKED(*rB, 32, 63);
2603 CR_COMPARE(BF, a, b);
2605 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2609 # I.3.3.11 Fixed-Point Trap Instructions
2612 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2614 program_interrupt(processor, cia,
2615 illegal_instruction_program_interrupt);
2617 signed_word a = *rA;
2618 signed_word b = EXTS(SI);
2619 if ((a < b && TO{0})
2621 || (a == b && TO{2})
2622 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2623 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2625 program_interrupt(processor, cia,
2626 trap_program_interrupt);
2629 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2630 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2631 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2632 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2633 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2634 signed_word a = EXTENDED(*rA);
2635 signed_word b = EXTS(SI);
2636 if ((a < b && TO{0})
2638 || (a == b && TO{2})
2639 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2640 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2642 program_interrupt(processor, cia,
2643 trap_program_interrupt);
2645 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2647 program_interrupt(processor, cia,
2648 illegal_instruction_program_interrupt);
2650 signed_word a = *rA;
2651 signed_word b = *rB;
2652 if ((a < b && TO{0})
2654 || (a == b && TO{2})
2655 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2656 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2658 program_interrupt(processor, cia,
2659 trap_program_interrupt);
2662 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2663 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2664 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2665 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2666 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2667 signed_word a = EXTENDED(*rA);
2668 signed_word b = EXTENDED(*rB);
2669 if (TO == 12 && rA == rB) {
2670 ITRACE(trace_breakpoint, ("breakpoint\n"));
2671 cpu_halt(processor, cia, was_trap, 0);
2673 else if ((a < b && TO{0})
2675 || (a == b && TO{2})
2676 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2677 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2679 program_interrupt(processor, cia,
2680 trap_program_interrupt);
2683 # I.3.3.12 Fixed-Point Logical Instructions
2686 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2687 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2688 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2689 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2690 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2692 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2693 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2694 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2696 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2697 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2698 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2699 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2700 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2701 *rA = *rS & (UI << 16);
2702 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2703 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2704 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2706 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2707 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2708 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2709 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2710 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2712 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2713 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2715 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2716 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2717 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2718 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2719 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2720 *rA = *rS | (UI << 16);
2721 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2722 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2724 0.26,6.RS,11.RA,16.UI:D:::XOR 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.27,6.RS,11.RA,16.UI:D:::XOR 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.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
2743 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2744 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2745 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2746 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2748 CR0_COMPARE(*rA, 0, Rc);
2749 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2750 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2752 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
2753 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2754 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2755 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2756 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2758 CR0_COMPARE(*rA, 0, Rc);
2759 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2760 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2762 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
2763 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2764 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2765 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2766 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2768 CR0_COMPARE(*rA, 0, Rc);
2769 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2770 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2772 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
2773 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2774 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2775 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2776 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2778 CR0_COMPARE(*rA, 0, Rc);
2779 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2780 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2782 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
2783 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2784 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2785 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2786 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2788 CR0_COMPARE(*rA, 0, Rc);
2789 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2790 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2792 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
2793 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2794 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2795 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2796 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2797 *rA = ~(*rS ^ *rB); /* A === B */
2798 CR0_COMPARE(*rA, 0, Rc);
2799 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2800 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2802 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
2803 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2804 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2805 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2806 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2808 CR0_COMPARE(*rA, 0, Rc);
2809 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2810 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2812 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
2813 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2814 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2815 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2816 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2818 CR0_COMPARE(*rA, 0, Rc);
2819 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2820 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2822 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
2823 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2824 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2825 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2826 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2827 *rA = (signed_word)(signed8)*rS;
2828 CR0_COMPARE(*rA, 0, Rc);
2829 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2830 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2832 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
2833 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2834 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2835 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2836 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2837 *rA = (signed_word)(signed16)*rS;
2838 CR0_COMPARE(*rA, 0, Rc);
2839 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2840 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2842 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2843 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2844 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2845 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2846 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2847 # *rA = (signed_word)(signed32)*rS;
2848 # CR0_COMPARE(*rA, 0, Rc);
2850 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2852 # unsigned64 mask = BIT64(0);
2853 # unsigned64 source = *rS;
2854 # while (!(source & mask) && mask != 0) {
2859 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2861 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
2862 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2863 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2864 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2865 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2867 unsigned32 mask = BIT32(0);
2868 unsigned32 source = *rS;
2869 while (!(source & mask) && mask != 0) {
2874 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2875 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2879 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2882 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
2883 # long n = (sh_5 << 4) | sh_0_4;
2884 # unsigned_word r = ROTL64(*rS, n);
2885 # long b = (mb_5 << 4) | mb_0_4;
2886 # unsigned_word m = MASK(b, 63);
2887 # signed_word result = r & m;
2889 # ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2890 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2892 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
2893 # long n = (sh_5 << 4) | sh_0_4;
2894 # unsigned_word r = ROTL64(*rS, n);
2895 # long e = (me_5 << 4) | me_0_4;
2896 # unsigned_word m = MASK(0, e);
2897 # signed_word result = r & m;
2899 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2901 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
2902 # long n = (sh_5 << 4) | sh_0_4;
2903 # unsigned_word r = ROTL64(*rS, n);
2904 # long b = (mb_5 << 4) | mb_0_4;
2905 # unsigned_word m = MASK(0, (64-n));
2906 # signed_word result = r & m;
2908 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2910 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2911 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2912 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2913 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2914 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2917 unsigned32 r = ROTL32(s, n);
2918 unsigned32 m = MASK(MB+32, ME+32);
2919 signed_word result = r & m;
2921 CR0_COMPARE(result, 0, Rc);
2923 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
2924 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
2925 (unsigned long)result, (unsigned long)CR));
2926 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2928 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2929 # long n = MASKED(*rB, 58, 63);
2930 # unsigned_word r = ROTL64(*rS, n);
2931 # long b = (mb_5 << 4) | mb_0_4;
2932 # unsigned_word m = MASK(b, 63);
2933 # signed_word result = r & m;
2935 # CR0_COMPARE(result, 0, Rc);
2937 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2938 # long n = MASKED(*rB, 58, 63);
2939 # unsigned_word r = ROTL64(*rS, n);
2940 # long e = (me_5 << 4) | me_0_4;
2941 # unsigned_word m = MASK(0, e);
2942 # signed_word result = r & m;
2944 # CR0_COMPARE(result, 0, Rc);
2946 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2947 # long n = MASKED(*rB, 59, 63);
2948 # unsigned32 r = ROTL32(*rS, n);
2949 # unsigned32 m = MASK(MB+32, ME+32);
2950 # signed_word result = r & m;
2952 # CR0_COMPARE(result, 0, Rc);
2954 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
2955 # long n = (sh_5 << 4) | sh_0_4;
2956 # unsigned_word r = ROTL64(*rS, n);
2957 # long b = (mb_5 << 4) | mb_0_4;
2958 # unsigned_word m = MASK(b, (64-n));
2959 # signed_word result = (r & m) | (*rA & ~m)
2961 # CR0_COMPARE(result, 0, Rc);
2963 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2964 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2965 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2966 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2967 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2969 unsigned32 r = ROTL32(*rS, n);
2970 unsigned32 m = MASK(MB+32, ME+32);
2971 signed_word result = (r & m) | (*rA & ~m);
2973 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
2974 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
2975 (unsigned long)result));
2976 CR0_COMPARE(result, 0, Rc);
2977 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2980 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2982 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2983 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2984 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2985 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2986 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2987 int n = MASKED(*rB, 59, 63);
2988 unsigned32 source = *rS;
2989 signed_word shifted;
2991 shifted = (source << n);
2995 CR0_COMPARE(shifted, 0, Rc);
2997 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2998 n, (unsigned long)source, (unsigned long)shifted));
2999 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3001 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3003 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
3004 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3005 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3006 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3007 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3008 int n = MASKED(*rB, 59, 63);
3009 unsigned32 source = *rS;
3010 signed_word shifted;
3012 shifted = (source >> n);
3016 CR0_COMPARE(shifted, 0, Rc);
3018 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3019 n, (unsigned long)source, (unsigned long)shifted));
3020 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3022 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3024 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3025 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3026 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3027 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3028 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3030 signed_word r = ROTL32(*rS, /*64*/32-n);
3031 signed_word m = MASK(n+32, 63);
3032 int S = MASKED(*rS, 32, 32);
3033 signed_word shifted = (r & m) | (S ? ~m : 0);
3035 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3039 CR0_COMPARE(shifted, 0, Rc);
3040 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3041 (long)*rA, (long)*rA, (long)XER));
3042 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3044 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3046 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3047 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3048 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3049 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3050 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3051 int n = MASKED(*rB, 58, 63);
3052 int shift = (n >= 31 ? 31 : n);
3053 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3054 signed32 shifted = source >> shift;
3055 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
3056 *rA = (signed_word)shifted; /* if 64bit will sign extend */
3057 if (source < 0 && (source & mask))
3061 CR0_COMPARE(shifted, 0, Rc);
3062 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3063 (long)*rA, (long)*rA, (long)XER));
3064 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3067 # I.3.3.14 Move to/from System Register Instructions
3070 0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3071 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3072 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3073 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3074 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3075 int n = (SPR{5:9} << 5) | SPR{0:4};
3076 if (SPR{0} && IS_PROBLEM_STATE(processor))
3077 program_interrupt(processor, cia,
3078 privileged_instruction_program_interrupt);
3079 else if (!spr_is_valid(n)
3080 || spr_is_readonly(n))
3081 program_interrupt(processor, cia,
3082 illegal_instruction_program_interrupt);
3084 spreg new_val = (spr_length(n) == 64
3086 : MASKED(*rS, 32, 63));
3087 /* HACK - time base registers need to be updated immediatly */
3088 if (WITH_TIME_BASE) {
3091 cpu_set_time_base(processor,
3092 (MASKED64(cpu_get_time_base(processor), 32, 63)
3093 | INSERTED64(new_val, 0, 31)));
3096 cpu_set_time_base(processor,
3097 (MASKED64(cpu_get_time_base(processor), 0, 31)
3098 | INSERTED64(new_val, 32, 63)));
3101 cpu_set_decrementer(processor, new_val);
3112 PPC_INSN_TO_SPR(RS_BITMASK, n);
3114 0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3115 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3116 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3117 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3118 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3119 int n = (SPR{5:9} << 5) | SPR{0:4};
3120 if (SPR{0} && IS_PROBLEM_STATE(processor))
3121 program_interrupt(processor, cia,
3122 privileged_instruction_program_interrupt);
3123 else if (!spr_is_valid(n))
3124 program_interrupt(processor, cia,
3125 illegal_instruction_program_interrupt);
3127 /* HACK - some SPR's need to get their value extracted specially */
3130 PPC_INSN_FROM_SPR(RT_BITMASK, n);
3132 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3133 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 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, 1, 1, 0
3141 unsigned_word mask = 0;
3143 for (f = 0; f < 8; f++) {
3144 if (FXM & (0x80 >> f))
3145 mask |= (0xf << 4*(7-f));
3147 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3149 PPC_INSN_MTCR(RS_BITMASK, FXM);
3151 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3153 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3154 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3155 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3156 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3157 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3158 *rT = (unsigned32)CR;
3159 PPC_INSN_MFCR(RT_BITMASK);
3162 # I.4.6.2 Floating-Point Load Instructions
3165 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3166 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3167 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3168 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3169 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3175 *frT = DOUBLE(MEM(unsigned, EA, 4));
3176 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3178 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3179 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3180 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3181 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3182 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3188 *frT = DOUBLE(MEM(unsigned, EA, 4));
3189 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3191 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3192 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3193 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3194 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3195 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3198 program_interrupt(processor, cia,
3199 illegal_instruction_program_interrupt);
3201 *frT = DOUBLE(MEM(unsigned, EA, 4));
3203 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3205 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3206 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3207 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3208 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3209 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3212 program_interrupt(processor, cia,
3213 illegal_instruction_program_interrupt);
3215 *frT = DOUBLE(MEM(unsigned, EA, 4));
3217 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3219 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3220 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3221 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3222 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3223 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3229 *frT = MEM(unsigned, EA, 8);
3230 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3232 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3233 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3234 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3235 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3236 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3242 *frT = MEM(unsigned, EA, 8);
3243 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3245 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3246 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3247 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3248 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3249 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3252 program_interrupt(processor, cia,
3253 illegal_instruction_program_interrupt);
3255 *frT = MEM(unsigned, EA, 8);
3257 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3259 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3260 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3261 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3262 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3263 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3266 program_interrupt(processor, cia,
3267 illegal_instruction_program_interrupt);
3269 *frT = MEM(unsigned, EA, 8);
3271 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3275 # I.4.6.3 Floating-Point Store Instructions
3278 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3279 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3280 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3281 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3282 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3288 STORE(EA, 4, SINGLE(*frS));
3289 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3291 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3292 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3293 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3294 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3295 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3301 STORE(EA, 4, SINGLE(*frS));
3302 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3304 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3305 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3306 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3307 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3308 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3311 program_interrupt(processor, cia,
3312 illegal_instruction_program_interrupt);
3314 STORE(EA, 4, SINGLE(*frS));
3316 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3318 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3319 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3320 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3321 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3322 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3325 program_interrupt(processor, cia,
3326 illegal_instruction_program_interrupt);
3328 STORE(EA, 4, SINGLE(*frS));
3330 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3332 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3333 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3334 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3335 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3336 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3343 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3345 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3346 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3347 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3348 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3349 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3356 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3358 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3359 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3360 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3361 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3362 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3365 program_interrupt(processor, cia,
3366 illegal_instruction_program_interrupt);
3370 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3372 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3373 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3374 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3375 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3376 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3379 program_interrupt(processor, cia,
3380 illegal_instruction_program_interrupt);
3384 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3388 # I.4.6.4 Floating-Point Move Instructions
3391 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3392 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3393 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3394 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3395 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3398 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3400 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3401 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3402 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3403 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3404 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3405 *frT = *frB ^ BIT64(0);
3407 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3409 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
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
3414 *frT = *frB & ~BIT64(0);
3416 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3418 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
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);
3429 # I.4.6.5 Floating-Point Arithmetic Instructions
3432 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3433 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3434 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3435 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3436 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3438 if (is_invalid_operation(processor, cia,
3440 fpscr_vxsnan | fpscr_vxisi,
3443 invalid_arithemetic_operation(processor, cia,
3445 0, /*instruction_is_frsp*/
3446 0, /*instruction_is_convert_to_64bit*/
3447 0, /*instruction_is_convert_to_32bit*/
3448 0); /*single-precision*/
3452 double s = *(double*)frA + *(double*)frB;
3456 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3458 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3459 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3460 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3461 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3462 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3464 if (is_invalid_operation(processor, cia,
3466 fpscr_vxsnan | fpscr_vxisi,
3469 invalid_arithemetic_operation(processor, cia,
3471 0, /*instruction_is_frsp*/
3472 0, /*instruction_is_convert_to_64bit*/
3473 0, /*instruction_is_convert_to_32bit*/
3474 1); /*single-precision*/
3478 float s = *(double*)frA + *(double*)frB;
3482 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3484 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3485 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3486 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3487 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3488 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3490 if (is_invalid_operation(processor, cia,
3492 fpscr_vxsnan | fpscr_vxisi,
3495 invalid_arithemetic_operation(processor, cia,
3497 0, /*instruction_is_frsp*/
3498 0, /*instruction_is_convert_to_64bit*/
3499 0, /*instruction_is_convert_to_32bit*/
3500 0); /*single-precision*/
3504 double s = *(double*)frA - *(double*)frB;
3508 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3510 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3511 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3512 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3513 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3514 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3516 if (is_invalid_operation(processor, cia,
3518 fpscr_vxsnan | fpscr_vxisi,
3521 invalid_arithemetic_operation(processor, cia,
3523 0, /*instruction_is_frsp*/
3524 0, /*instruction_is_convert_to_64bit*/
3525 0, /*instruction_is_convert_to_32bit*/
3526 1); /*single-precision*/
3530 float s = *(double*)frA - *(double*)frB;
3534 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3536 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3537 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3538 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3539 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3540 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3542 if (is_invalid_operation(processor, cia,
3544 fpscr_vxsnan | fpscr_vximz,
3547 invalid_arithemetic_operation(processor, cia,
3549 0, /*instruction_is_frsp*/
3550 0, /*instruction_is_convert_to_64bit*/
3551 0, /*instruction_is_convert_to_32bit*/
3552 0); /*single-precision*/
3556 double s = *(double*)frA * *(double*)frC;
3560 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3562 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3563 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3564 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3565 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3566 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3568 if (is_invalid_operation(processor, cia,
3570 fpscr_vxsnan | fpscr_vximz,
3573 invalid_arithemetic_operation(processor, cia,
3575 0, /*instruction_is_frsp*/
3576 0, /*instruction_is_convert_to_64bit*/
3577 0, /*instruction_is_convert_to_32bit*/
3578 1); /*single-precision*/
3582 float s = *(double*)frA * *(double*)frC;
3586 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3588 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3589 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3590 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3591 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3592 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3594 if (is_invalid_operation(processor, cia,
3596 fpscr_vxsnan | fpscr_vxzdz,
3599 invalid_arithemetic_operation(processor, cia,
3601 0, /*instruction_is_frsp*/
3602 0, /*instruction_is_convert_to_64bit*/
3603 0, /*instruction_is_convert_to_32bit*/
3604 0); /*single-precision*/
3608 double s = *(double*)frA / *(double*)frB;
3612 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3614 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3615 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3616 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3617 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3618 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3620 if (is_invalid_operation(processor, cia,
3622 fpscr_vxsnan | fpscr_vxzdz,
3625 invalid_arithemetic_operation(processor, cia,
3627 0, /*instruction_is_frsp*/
3628 0, /*instruction_is_convert_to_64bit*/
3629 0, /*instruction_is_convert_to_32bit*/
3630 1); /*single-precision*/
3634 float s = *(double*)frA / *(double*)frB;
3638 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3640 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3641 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3642 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3643 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3644 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3646 double product; /*HACK! - incorrectly loosing precision ... */
3647 /* compute the multiply */
3648 if (is_invalid_operation(processor, cia,
3650 fpscr_vxsnan | fpscr_vximz,
3653 invalid_arithemetic_operation(processor, cia,
3654 (unsigned64*)&product, *frA, 0, *frC,
3655 0, /*instruction_is_frsp*/
3656 0, /*instruction_is_convert_to_64bit*/
3657 0, /*instruction_is_convert_to_32bit*/
3658 0); /*single-precision*/
3662 product = *(double*)frA * *(double*)frC;
3664 /* compute the add */
3665 if (is_invalid_operation(processor, cia,
3667 fpscr_vxsnan | fpscr_vxisi,
3670 invalid_arithemetic_operation(processor, cia,
3671 frT, product, *frB, 0,
3672 0, /*instruction_is_frsp*/
3673 0, /*instruction_is_convert_to_64bit*/
3674 0, /*instruction_is_convert_to_32bit*/
3675 0); /*single-precision*/
3679 double s = product + *(double*)frB;
3683 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3685 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3686 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3687 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3688 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3689 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3691 float product; /*HACK! - incorrectly loosing precision ... */
3692 /* compute the multiply */
3693 if (is_invalid_operation(processor, cia,
3695 fpscr_vxsnan | fpscr_vximz,
3698 invalid_arithemetic_operation(processor, cia,
3699 (unsigned64*)&product, *frA, 0, *frC,
3700 0, /*instruction_is_frsp*/
3701 0, /*instruction_is_convert_to_64bit*/
3702 0, /*instruction_is_convert_to_32bit*/
3703 0); /*single-precision*/
3707 product = *(double*)frA * *(double*)frC;
3709 /* compute the add */
3710 if (is_invalid_operation(processor, cia,
3712 fpscr_vxsnan | fpscr_vxisi,
3715 invalid_arithemetic_operation(processor, cia,
3716 frT, product, *frB, 0,
3717 0, /*instruction_is_frsp*/
3718 0, /*instruction_is_convert_to_64bit*/
3719 0, /*instruction_is_convert_to_32bit*/
3720 0); /*single-precision*/
3724 float s = product + *(double*)frB;
3725 *(double*)frT = (double)s;
3728 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3730 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3731 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3732 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3733 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3734 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3736 double product; /*HACK! - incorrectly loosing precision ... */
3737 /* compute the multiply */
3738 if (is_invalid_operation(processor, cia,
3740 fpscr_vxsnan | fpscr_vximz,
3743 invalid_arithemetic_operation(processor, cia,
3744 (unsigned64*)&product, *frA, 0, *frC,
3745 0, /*instruction_is_frsp*/
3746 0, /*instruction_is_convert_to_64bit*/
3747 0, /*instruction_is_convert_to_32bit*/
3748 0); /*single-precision*/
3752 product = *(double*)frA * *(double*)frC;
3754 /* compute the subtract */
3755 if (is_invalid_operation(processor, cia,
3757 fpscr_vxsnan | fpscr_vxisi,
3760 invalid_arithemetic_operation(processor, cia,
3761 frT, product, *frB, 0,
3762 0, /*instruction_is_frsp*/
3763 0, /*instruction_is_convert_to_64bit*/
3764 0, /*instruction_is_convert_to_32bit*/
3765 0); /*single-precision*/
3769 double s = product - *(double*)frB;
3773 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3775 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
3776 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3777 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3778 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3779 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3781 float product; /*HACK! - incorrectly loosing precision ... */
3782 /* compute the multiply */
3783 if (is_invalid_operation(processor, cia,
3785 fpscr_vxsnan | fpscr_vximz,
3788 invalid_arithemetic_operation(processor, cia,
3789 (unsigned64*)&product, *frA, 0, *frC,
3790 0, /*instruction_is_frsp*/
3791 0, /*instruction_is_convert_to_64bit*/
3792 0, /*instruction_is_convert_to_32bit*/
3793 0); /*single-precision*/
3797 product = *(double*)frA * *(double*)frC;
3799 /* compute the subtract */
3800 if (is_invalid_operation(processor, cia,
3802 fpscr_vxsnan | fpscr_vxisi,
3805 invalid_arithemetic_operation(processor, cia,
3806 frT, product, *frB, 0,
3807 0, /*instruction_is_frsp*/
3808 0, /*instruction_is_convert_to_64bit*/
3809 0, /*instruction_is_convert_to_32bit*/
3810 0); /*single-precision*/
3814 float s = product - *(double*)frB;
3815 *(double*)frT = (double)s;
3818 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3820 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
3821 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3822 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3823 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3824 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3826 double product; /*HACK! - incorrectly loosing precision ... */
3827 /* compute the multiply */
3828 if (is_invalid_operation(processor, cia,
3830 fpscr_vxsnan | fpscr_vximz,
3833 invalid_arithemetic_operation(processor, cia,
3834 (unsigned64*)&product, *frA, 0, *frC,
3835 0, /*instruction_is_frsp*/
3836 0, /*instruction_is_convert_to_64bit*/
3837 0, /*instruction_is_convert_to_32bit*/
3838 0); /*single-precision*/
3842 product = *(double*)frA * *(double*)frC;
3844 /* compute the add */
3845 if (is_invalid_operation(processor, cia,
3847 fpscr_vxsnan | fpscr_vxisi,
3850 invalid_arithemetic_operation(processor, cia,
3851 frT, product, *frB, 0,
3852 0, /*instruction_is_frsp*/
3853 0, /*instruction_is_convert_to_64bit*/
3854 0, /*instruction_is_convert_to_32bit*/
3855 0); /*single-precision*/
3859 double s = -(product + *(double*)frB);
3863 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3865 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
3866 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3867 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3868 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3869 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3871 float product; /*HACK! - incorrectly loosing precision ... */
3872 /* compute the multiply */
3873 if (is_invalid_operation(processor, cia,
3875 fpscr_vxsnan | fpscr_vximz,
3878 invalid_arithemetic_operation(processor, cia,
3879 (unsigned64*)&product, *frA, 0, *frC,
3880 0, /*instruction_is_frsp*/
3881 0, /*instruction_is_convert_to_64bit*/
3882 0, /*instruction_is_convert_to_32bit*/
3883 0); /*single-precision*/
3887 product = *(double*)frA * *(double*)frC;
3889 /* compute the add */
3890 if (is_invalid_operation(processor, cia,
3892 fpscr_vxsnan | fpscr_vxisi,
3895 invalid_arithemetic_operation(processor, cia,
3896 frT, product, *frB, 0,
3897 0, /*instruction_is_frsp*/
3898 0, /*instruction_is_convert_to_64bit*/
3899 0, /*instruction_is_convert_to_32bit*/
3900 0); /*single-precision*/
3904 float s = -(product + *(double*)frB);
3905 *(double*)frT = (double)s;
3908 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3910 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
3911 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3912 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3913 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3914 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3916 double product; /*HACK! - incorrectly loosing precision ... */
3917 /* compute the multiply */
3918 if (is_invalid_operation(processor, cia,
3920 fpscr_vxsnan | fpscr_vximz,
3923 invalid_arithemetic_operation(processor, cia,
3924 (unsigned64*)&product, *frA, 0, *frC,
3925 0, /*instruction_is_frsp*/
3926 0, /*instruction_is_convert_to_64bit*/
3927 0, /*instruction_is_convert_to_32bit*/
3928 0); /*single-precision*/
3932 product = *(double*)frA * *(double*)frC;
3934 /* compute the subtract */
3935 if (is_invalid_operation(processor, cia,
3937 fpscr_vxsnan | fpscr_vxisi,
3940 invalid_arithemetic_operation(processor, cia,
3941 frT, product, *frB, 0,
3942 0, /*instruction_is_frsp*/
3943 0, /*instruction_is_convert_to_64bit*/
3944 0, /*instruction_is_convert_to_32bit*/
3945 0); /*single-precision*/
3949 double s = -(product - *(double*)frB);
3953 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3955 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
3956 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3957 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3958 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3959 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3961 float product; /*HACK! - incorrectly loosing precision ... */
3962 /* compute the multiply */
3963 if (is_invalid_operation(processor, cia,
3965 fpscr_vxsnan | fpscr_vximz,
3968 invalid_arithemetic_operation(processor, cia,
3969 (unsigned64*)&product, *frA, 0, *frC,
3970 0, /*instruction_is_frsp*/
3971 0, /*instruction_is_convert_to_64bit*/
3972 0, /*instruction_is_convert_to_32bit*/
3973 0); /*single-precision*/
3977 product = *(double*)frA * *(double*)frC;
3979 /* compute the subtract */
3980 if (is_invalid_operation(processor, cia,
3982 fpscr_vxsnan | fpscr_vxisi,
3985 invalid_arithemetic_operation(processor, cia,
3986 frT, product, *frB, 0,
3987 0, /*instruction_is_frsp*/
3988 0, /*instruction_is_convert_to_64bit*/
3989 0, /*instruction_is_convert_to_32bit*/
3990 0); /*single-precision*/
3994 float s = -(product - *(double*)frB);
3995 *(double*)frT = (double)s;
3998 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4002 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4005 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4006 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4007 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4008 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4009 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4012 unsigned64 frac_grx;
4013 enum { start, finish, Disabled_Exponent_Underflow, Enabled_Exponent_Underflow, Disabled_Exponent_Overflow, Enabled_Exponent_Overflow, Normal_Operand, Zero_Operand, Infinity_Operand, QNaN_Operand, SNaN_Operand, Enabled_Overflow, Done } label = start;
4014 while (label != finish) switch (label) {
4016 error("Unhandled switch\n");
4018 /* split off cases for what to do */
4019 if (EXTRACTED64(*frB, 1, 11) < 897
4020 && EXTRACTED64(*frB, 1, 63) > 0) {
4021 if ((FPSCR & fpscr_ue) == 0) { label = Disabled_Exponent_Underflow; break; }
4022 if ((FPSCR & fpscr_ue) != 0) { label = Enabled_Exponent_Underflow; break; }
4024 if (EXTRACTED64(*frB, 1, 11) > 1150
4025 && EXTRACTED64(*frB, 1, 11) < 2047) {
4026 if ((FPSCR & fpscr_oe) == 0) { label = Disabled_Exponent_Overflow; break; }
4027 if ((FPSCR & fpscr_oe) != 0) { label = Enabled_Exponent_Overflow; break; }
4029 if (EXTRACTED64(*frB, 1, 11) > 896
4030 && EXTRACTED64(*frB, 1, 11) < 1151) { label = Normal_Operand; break; }
4031 if (EXTRACTED64(*frB, 1, 63) == 0) { label = Zero_Operand; break; }
4032 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4033 if (EXTRACTED64(*frB, 12, 63) == 0) { label = Infinity_Operand; break; }
4034 if (EXTRACTED64(*frB, 12, 12) == 1) { label = QNaN_Operand; break; }
4035 if (EXTRACTED64(*frB, 12, 12) == 0
4036 && EXTRACTED64(*frB, 13, 63) > 0) { label = SNaN_Operand; break; }
4038 case Disabled_Exponent_Underflow:
4039 sign = EXTRACTED64(*frB, 0, 0);
4040 if (EXTRACTED64(*frB, 1, 11) == 0) {
4042 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4044 if (EXTRACTED64(*frB, 1, 11) > 0) {
4045 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4046 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4048 /* G|R|X == zero from above */
4049 while (exp < -126) {
4051 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4052 | MASKED64(frac_grx, 55, 55));
4054 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4055 Round_Single(processor, sign, &exp, &frac_grx);
4056 FPSCR_SET_XX(FPSCR & fpscr_fi);
4057 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4058 *frT = INSERTED64(sign, 0, 0);
4059 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4060 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4062 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4063 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4064 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4065 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4067 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4068 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4069 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4071 /*Normalize_Operand:*/
4072 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4074 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4076 *frT = (INSERTED64(sign, 0, 0)
4077 | INSERTED64(exp + 1023, 1, 11)
4078 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4080 { label = Done; break; }
4081 case Enabled_Exponent_Underflow:
4083 sign = EXTRACTED64(*frB, 0, 0);
4084 if (EXTRACTED64(*frB, 1, 11) == 0) {
4086 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4088 if (EXTRACTED64(*frB, 1, 11) > 0) {
4089 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4090 frac_grx = (BIT64(0) |
4091 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4093 /*Normalize_Operand:*/
4094 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4096 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4098 Round_Single(processor, sign, &exp, &frac_grx);
4099 FPSCR_SET_XX(FPSCR & fpscr_fi);
4101 *frT = (INSERTED64(sign, 0, 0)
4102 | INSERTED64(exp + 1023, 1, 11)
4103 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4104 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4105 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4106 { label = Done; break; }
4107 case Disabled_Exponent_Overflow:
4109 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4110 if (EXTRACTED64(*frB, 0, 0) == 0) {
4111 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4112 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4114 if (EXTRACTED64(*frB, 0, 0) == 1) {
4115 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4116 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4119 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4120 if (EXTRACTED64(*frB, 0, 0) == 0) {
4121 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4122 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4124 if (EXTRACTED64(*frB, 0, 0) == 1) {
4125 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4126 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4129 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4130 if (EXTRACTED64(*frB, 0, 0) == 0) {
4131 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4132 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4134 if (EXTRACTED64(*frB, 0, 0) == 1) {
4135 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4136 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4139 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4140 if (EXTRACTED64(*frB, 0, 0) == 0) {
4141 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4142 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4144 if (EXTRACTED64(*frB, 0, 0) == 1) {
4145 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4146 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4149 /* FPSCR[FR] <- undefined */
4152 { label = Done; break; }
4153 case Enabled_Exponent_Overflow:
4154 sign = EXTRACTED64(*frB, 0, 0);
4155 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4156 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4157 Round_Single(processor, sign, &exp, &frac_grx);
4158 FPSCR_SET_XX(FPSCR & fpscr_fi);
4159 case Enabled_Overflow:
4162 *frT = (INSERTED64(sign, 0, 0)
4163 | INSERTED64(exp + 1023, 1, 11)
4164 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4165 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4166 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4167 { label = Done; break; }
4170 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4171 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4174 { label = Done; break; }
4175 case Infinity_Operand:
4177 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4178 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4181 { label = Done; break; }
4183 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4184 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4187 { label = Done; break; }
4189 FPSCR_OR_VX(fpscr_vxsnan);
4190 if ((FPSCR & fpscr_ve) == 0) {
4191 *frT = (MASKED64(*frB, 0, 11)
4193 | MASKED64(*frB, 13, 34));
4194 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4198 { label = Done; break; }
4199 case Normal_Operand:
4200 sign = EXTRACTED64(*frB, 0, 0);
4201 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4202 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4203 Round_Single(processor, sign, &exp, &frac_grx);
4204 FPSCR_SET_XX(FPSCR & fpscr_fi);
4205 if (exp > 127 && (FPSCR & fpscr_oe) == 0) { label = Disabled_Exponent_Overflow; break; }
4206 if (exp > 127 && (FPSCR & fpscr_oe) != 0) { label = Enabled_Overflow; break; }
4207 *frT = (INSERTED64(sign, 0, 0)
4208 | INSERTED64(exp + 1023, 1, 11)
4209 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4210 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4211 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4212 { label = Done; break; }
4214 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4215 { label = finish; break; }
4218 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4220 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4222 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4224 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4225 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4226 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4227 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4228 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4230 convert_to_integer(processor, cia,
4232 fpscr_rn_round_towards_zero, 32);
4234 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4236 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4237 int sign = EXTRACTED64(*frB, 0, 0);
4239 unsigned64 frac = *frB;
4240 enum { start, finish, Zero_Operand, Done } label = start;
4241 while (label != finish) switch (label) {
4243 error("Unhandled switch\n");
4245 if (frac == 0) { label = Zero_Operand; break; }
4246 if (sign == 1) frac = ~frac + 1;
4247 while (EXTRACTED64(frac, 0, 0) == 0) {
4248 /*??? do the loop 0 times if (FRB) = max negative integer */
4249 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4252 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4253 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4254 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4255 *frT = (INSERTED64(sign, 0, 0)
4256 | INSERTED64(exp + 1023, 1, 11)
4257 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4258 { label = Done; break; }
4263 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4265 { label = Done; break; }
4268 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4269 { label = finish; break; }
4273 # I.4.6.7 Floating-Point Compare Instructions
4276 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4277 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4278 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4279 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4280 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4283 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4284 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4285 else if (is_less_than(frA, frB))
4286 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4287 else if (is_greater_than(frA, frB))
4288 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4290 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4292 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4293 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4294 FPSCR_OR_VX(fpscr_vxsnan);
4296 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4298 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4299 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4300 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4301 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4302 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4305 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4306 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4307 else if (is_less_than(frA, frB))
4308 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4309 else if (is_greater_than(frA, frB))
4310 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4312 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4314 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4315 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4316 FPSCR_OR_VX(fpscr_vxsnan);
4317 if ((FPSCR & fpscr_ve) == 0)
4318 FPSCR_OR_VX(fpscr_vxvc);
4320 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4321 FPSCR_OR_VX(fpscr_vxvc);
4324 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4328 # I.4.6.8 Floating-Point Status and Control Register Instructions
4331 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4333 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4335 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4337 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4339 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4341 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4345 # I.A.1.1 Floating-Point Store Instruction
4347 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4350 # I.A.1.2 Floating-Point Arithmetic Instructions
4353 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
4355 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4357 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
4359 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4362 # I.A.1.3 Floating-Point Select Instruction
4365 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4369 # II.3.2 Cache Management Instructions
4372 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4373 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4374 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4375 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4376 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4377 /* blindly flush all instruction cache entries */
4378 #if WITH_IDECODE_CACHE_SIZE
4379 cpu_flush_icache(processor);
4381 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4383 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4384 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4385 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4386 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4387 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4388 cpu_synchronize_context(processor);
4389 PPC_INSN_INT(0, 0, 0);
4393 # II.3.2.2 Data Cache Instructions
4396 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4397 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4398 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4399 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4400 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4401 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4402 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4404 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4405 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4406 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4407 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4408 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4409 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4410 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4412 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4413 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4414 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4415 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4416 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4417 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4418 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4420 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4421 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4422 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4423 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4424 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4425 TRACE(trace_tbd,("Data Cache Block Store\n"));
4426 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4428 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4429 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4430 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4431 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4432 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4433 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4434 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4437 # II.3.3 Enforce In-order Execution of I/O Instruction
4440 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4441 /* Since this model has no instruction overlap
4442 this instruction need do nothing */
4445 # II.4.1 Time Base Instructions
4448 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4449 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4450 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4451 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4452 int n = (tbr{5:9} << 5) | tbr{0:4};
4454 if (is_64bit_implementation) *rT = TB;
4455 else *rT = EXTRACTED64(TB, 32, 63);
4457 else if (n == 269) {
4458 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4459 else *rT = EXTRACTED64(TB, 0, 31);
4462 program_interrupt(processor, cia,
4463 illegal_instruction_program_interrupt);
4467 # III.2.3.1 System Linkage Instructions
4470 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4471 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4472 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4473 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4474 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4475 if (IS_PROBLEM_STATE(processor)) {
4476 program_interrupt(processor, cia,
4477 privileged_instruction_program_interrupt);
4480 MSR = (MASKED(SRR1, 0, 32)
4481 | MASKED(SRR1, 37, 41)
4482 | MASKED(SRR1, 48, 63));
4483 NIA = MASKED(SRR0, 0, 61);
4484 cpu_synchronize_context(processor);
4485 check_masked_interrupts(processor);
4489 # III.3.4.1 Move to/from System Register Instructions
4492 #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4493 #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4494 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4495 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4496 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4497 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4498 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4499 if (IS_PROBLEM_STATE(processor))
4500 program_interrupt(processor, cia,
4501 privileged_instruction_program_interrupt);
4504 check_masked_interrupts(processor);
4507 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4508 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4509 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4510 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4511 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4512 if (IS_PROBLEM_STATE(processor))
4513 program_interrupt(processor, cia,
4514 privileged_instruction_program_interrupt);
4517 check_masked_interrupts(processor);
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
4594 if (IS_PROBLEM_STATE(processor))
4595 program_interrupt(processor, cia,
4596 privileged_instruction_program_interrupt);
4601 proc = psim_cpu(cpu_system(processor), nr);
4602 if (proc == NULL) break;
4603 cpu_page_tlb_invalidate_entry(proc, *rB);
4608 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4609 if (IS_PROBLEM_STATE(processor))
4610 program_interrupt(processor, cia,
4611 privileged_instruction_program_interrupt);
4616 proc = psim_cpu(cpu_system(processor), nr);
4617 if (proc == NULL) break;
4618 cpu_page_tlb_invalidate_all(proc);
4623 0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
4624 /* nothing happens here - always in sync */
4627 # III.A.1.2 External Access Instructions
4630 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4632 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed