2 # This file is part of the program psim.
8 # The pseudo-code that appears below, translated into C, was copied
9 # by Andrew Cagney of Moss Vale, Australia.
11 # This pseudo-code is copied by permission from the publication
12 # "The PowerPC Architecture: A Specification for A New Family of
13 # RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by
14 # International Business Machines Corporation.
16 # THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER
17 # EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES
18 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 # This program is free software; you can redistribute it and/or modify
23 # it under the terms of the GNU General Public License as published by
24 # the Free Software Foundation; either version 2 of the License, or
25 # (at your option) any later version.
27 # This program is distributed in the hope that it will be useful,
28 # but WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 # GNU General Public License for more details.
32 # You should have received a copy of the GNU General Public License
33 # along with this program; if not, write to the Free Software
34 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 # 1 Instruction format as a `start-bit,content' pairs.
42 # the content is one of a digit, field name or `/' (aka.0)
46 # 3 Flags: 64 - 64bit only
47 # f - floating point enabled required
54 # For flags marked 'model', the fields are interpreted as follows:
62 # 4 String name for model
64 # 5 Specific CPU model, must be an identifier
66 # 6 Comma separated list of functional units
70 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
71 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
72 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
73 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
77 #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \
79 if (WITH_MODEL_ISSUE) { \
81 ppc_insn_int(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \
83 ppc_insn_int_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
87 #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \
89 if (WITH_MODEL_ISSUE) \
90 ppc_insn_int_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
93 #define PPC_INSN_CR(OUT_MASK, IN_MASK) \
95 if (WITH_MODEL_ISSUE) \
96 ppc_insn_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \
99 #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \
101 if (WITH_MODEL_ISSUE) { \
103 ppc_insn_float(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \
105 ppc_insn_float_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
109 #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \
111 if (WITH_MODEL_ISSUE) \
112 ppc_insn_float_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
115 #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \
117 if (WITH_MODEL_ISSUE) \
118 ppc_insn_int_float(my_index, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \
121 #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \
123 if (WITH_MODEL_ISSUE) \
124 ppc_insn_from_spr(my_index, cpu_model(processor), INT_MASK, SPR); \
127 #define PPC_INSN_TO_SPR(INT_MASK, SPR) \
129 if (WITH_MODEL_ISSUE) \
130 ppc_insn_to_spr(my_index, cpu_model(processor), INT_MASK, SPR); \
133 #define PPC_INSN_MFCR(INT_MASK) \
135 if (WITH_MODEL_ISSUE) \
136 ppc_insn_mfcr(my_index, cpu_model(processor), INT_MASK); \
139 #define PPC_INSN_MTCR(INT_MASK, FXM) \
141 if (WITH_MODEL_ISSUE) \
142 ppc_insn_mtcr(my_index, cpu_model(processor), INT_MASK, FXM); \
146 typedef enum _ppc_function_unit {
147 PPC_UNIT_BAD, /* unknown function unit */
148 PPC_UNIT_IU, /* integer unit (601/603 style) */
149 PPC_UNIT_SRU, /* system register unit (601/603 style) */
150 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
151 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
152 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
153 PPC_UNIT_FPU, /* floating point unit */
154 PPC_UNIT_LSU, /* load/store unit */
155 PPC_UNIT_BPU, /* branch unit */
156 nr_ppc_function_units
159 /* Structure to hold timing information on a per instruction basis */
161 ppc_function_unit first_unit; /* first functional unit this insn could use */
162 ppc_function_unit second_unit; /* second functional unit this insn could use */
163 signed16 issue; /* # cycles before function unit can process other insns */
164 signed16 done; /* # cycles before insn is done */
165 unsigned32 flags; /* any flags that are needed */
168 /* Register mappings in status masks */
169 #define PPC_CR_REG 0 /* start of CR0 .. CR7 */
170 #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */
172 #define PPC_NO_SPR (-1) /* flag for no SPR register */
174 /* Structure for each functional unit that is busy */
175 typedef struct _model_busy model_busy;
177 model_busy *next; /* next function unit */
178 ppc_function_unit unit; /* function unit name */
179 unsigned32 int_busy; /* int registers that are busy */
180 unsigned32 fp_busy; /* floating point registers that are busy */
181 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
182 signed16 spr_busy; /* SPR register that is busy or PPC_NO_SPR */
183 signed8 issue; /* # of cycles until unit can accept another insn */
184 signed8 done; /* # of cycles until insn is done */
187 /* Structure to hold the current state information for the simulated CPU model */
189 cpu *processor; /* point back to processor */
190 const char *name; /* model name */
191 const model_time *timing; /* timing information */
192 model_busy *busy_list; /* list of busy function units */
193 model_busy *free_list; /* list of model_busy structs not in use */
194 count_type nr_cycles; /* # cycles */
195 count_type nr_branches; /* # branches */
196 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
197 count_type nr_branch_predict_trues; /* # branches predicted correctly */
198 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
199 count_type nr_branch_conditional[32]; /* # of each type of bc */
200 count_type nr_mtcrf_crs[9]; /* # of CR's moved in a mtcrf instruction */
201 count_type nr_stalls_data; /* # of stalls for data */
202 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
203 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
204 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
205 unsigned32 int_busy; /* int registers that are busy */
206 unsigned32 fp_busy; /* floating point registers that are busy */
207 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
208 unsigned8 spr_busy[nr_of_sprs]; /* SPR registers that are busy */
209 unsigned8 busy[nr_ppc_function_units]; /* whether a function is busy or not */
212 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
213 "unknown functional unit instruction",
214 "integer functional unit instruction",
215 "system register functional unit instruction",
216 "1st single cycle integer functional unit instruction",
217 "2nd single cycle integer functional unit instruction",
218 "multiple cycle integer functional unit instruction",
219 "floating point functional unit instruction",
220 "load/store functional unit instruction",
221 "branch functional unit instruction",
224 STATIC_MODEL const char *const ppc_branch_conditional_name[32] = {
225 "branch if --CTR != 0 and condition is FALSE", /* 0000y */
226 "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
227 "branch if --CTR == 0 and condition is FALSE", /* 0001y */
228 "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
229 "branch if the condition is FALSE", /* 001zy */
230 "branch if the condition is FALSE, reverse branch likely",
231 "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */
232 "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
233 "branch if --CTR != 0 and condition is TRUE", /* 0100y */
234 "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
235 "branch if --CTR == 0 and condition is TRUE", /* 0101y */
236 "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
237 "branch if the condition is TRUE", /* 011zy */
238 "branch if the condition is TRUE, reverse branch likely",
239 "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */
240 "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
241 "branch if --CTR != 0", /* 1z00y */
242 "branch if --CTR != 0, reverse branch likely",
243 "branch if --CTR == 0", /* 1z01y */
244 "branch if --CTR == 0, reverse branch likely",
245 "branch always", /* 1z1zz */
246 "branch always (ignored bit 5 set to 1)",
247 "branch always (ignored bit 4 set to 1)", /* 1z1zz */
248 "branch always (ignored bits 4,5 set to 1)",
249 "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */
250 "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
251 "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */
252 "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
253 "branch always (ignored bit 1 set to 1)", /* 1z1zz */
254 "branch always (ignored bits 1,5 set to 1)",
255 "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */
256 "branch always (ignored bits 1,4,5 set to 1)",
259 STATIC_MODEL const char *const ppc_nr_mtcrf_crs[9] = {
260 "mtcrf moving 0 CRs",
262 "mtcrf moving 2 CRs",
263 "mtcrf moving 3 CRs",
264 "mtcrf moving 4 CRs",
265 "mtcrf moving 5 CRs",
266 "mtcrf moving 6 CRs",
267 "mtcrf moving 7 CRs",
268 "mtcrf moving all CRs",
271 # Trace releasing resources
272 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
274 TRACE(trace_model,("done, %s\n", ppc_function_unit_name[busy->unit]));
275 if (busy->int_busy) {
276 for(i = 0; i < 32; i++) {
277 if (((1 << i) & busy->int_busy) != 0) {
278 TRACE(trace_model, ("Register r%d is now available.\n", i));
283 for(i = 0; i < 32; i++) {
284 if (((1 << i) & busy->fp_busy) != 0) {
285 TRACE(trace_model, ("Register f%d is now available.\n", i));
289 if (busy->cr_fpscr_busy) {
290 for(i = 0; i < 8; i++) {
291 if (((1 << i) & busy->cr_fpscr_busy) != 0) {
292 TRACE(trace_model, ("Register cr%d is now available.\n", i));
295 if (busy->cr_fpscr_busy & 0x100)
296 TRACE(trace_model, ("Register fpscr is now available.\n"));
298 if (busy->spr_busy != PPC_NO_SPR)
299 TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
301 # Trace making registers busy
302 void::model-static::model_trace_make_busy:model_data *model_ptr, unsigned32 int_mask, unsigned32 fp_mask, unsigned32 cr_mask
305 for(i = 0; i < 32; i++) {
306 if (((1 << i) & int_mask) != 0) {
307 TRACE(trace_model, ("Register r%d is now busy.\n", i));
312 for(i = 0; i < 32; i++) {
313 if (((1 << i) & fp_mask) != 0) {
314 TRACE(trace_model, ("Register f%d is now busy.\n", i));
319 for(i = 0; i < 8; i++) {
320 if (((1 << i) & cr_mask) != 0) {
321 TRACE(trace_model, ("Register cr%d is now busy.\n", i));
326 # Trace waiting for registers to become available
327 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
330 int_busy &= model_ptr->int_busy;
331 for(i = 0; i < 32; i++) {
332 if (((1 << i) & int_busy) != 0) {
333 TRACE(trace_model, ("Waiting for register r%d.\n", i));
338 fp_busy &= model_ptr->fp_busy;
339 for(i = 0; i < 32; i++) {
340 if (((1 << i) & fp_busy) != 0) {
341 TRACE(trace_model, ("Waiting for register f%d.\n", i));
345 if (cr_or_fpscr_busy) {
346 cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
347 for(i = 0; i < 8; i++) {
348 if (((1 << i) & cr_or_fpscr_busy) != 0) {
349 TRACE(trace_model, ("Waiting for register cr%d.\n", i));
352 if (cr_or_fpscr_busy & 0x100)
353 TRACE(trace_model, ("Waiting for register fpscr.\n"));
355 if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
356 TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
358 # Advance state to next cycle, releasing any registers allocated
359 void::model-internal::model_new_cycle:model_data *model_ptr
360 model_busy *cur_busy = model_ptr->busy_list;
361 model_busy *free_list = model_ptr->free_list;
362 model_busy *next_busy = (model_busy *)0;
365 model_ptr->nr_cycles++;
366 for ( ; cur_busy; cur_busy = next) {
367 next = cur_busy->next;
368 if (--cur_busy->done <= 0) { /* function unit done, release registers */
369 model_ptr->int_busy &= ~cur_busy->int_busy;
370 model_ptr->fp_busy &= ~cur_busy->fp_busy;
371 model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
372 if (cur_busy->spr_busy != PPC_NO_SPR)
373 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
375 if (WITH_TRACE && ppc_trace[trace_model])
376 model_trace_release(model_ptr, cur_busy);
378 model_ptr->busy[cur_busy->unit] = 0;
379 cur_busy->next = free_list;
380 free_list = cur_busy;
382 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
383 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
384 model_ptr->busy[cur_busy->unit] = 0;
385 cur_busy->next = next_busy;
386 next_busy = cur_busy;
389 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
390 ppc_function_unit_name[cur_busy->unit],
393 cur_busy->next = next_busy;
394 next_busy = cur_busy;
398 model_ptr->busy_list = next_busy;
399 model_ptr->free_list = free_list;
401 # Mark a function unit as busy, return the busy structure
402 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
405 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
407 if (!model_ptr->free_list) {
408 busy = ZALLOC(model_busy);
411 busy = model_ptr->free_list;
412 model_ptr->free_list = busy->next;
414 busy->next = model_ptr->busy_list;
420 busy->cr_fpscr_busy = 0;
421 busy->spr_busy = PPC_NO_SPR;
422 model_ptr->busy_list = busy;
423 model_ptr->busy[unit] = 1;
424 model_ptr->nr_units[unit]++;
427 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
428 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
429 ppc_function_unit first_unit = time_ptr->first_unit;
430 ppc_function_unit second_unit = time_ptr->second_unit;
431 int stall_increment = 0;
434 if (!model_ptr->busy[first_unit])
435 return model_make_busy(model_ptr, first_unit,
436 model_ptr->timing[index].issue,
437 model_ptr->timing[index].done);
439 if (!model_ptr->busy[second_unit])
440 return model_make_busy(model_ptr, second_unit,
441 model_ptr->timing[index].issue,
442 model_ptr->timing[index].done);
444 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
445 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
447 model_new_cycle(model_ptr);
450 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
451 void::model-function::model_serialize:itable_index index, model_data *model_ptr
452 while (model_ptr->busy_list) {
453 TRACE(trace_model,("waiting for pipeline to empty\n"));
454 model_ptr->nr_stalls_serialize++;
455 model_new_cycle(model_ptr);
457 (void) model_make_busy(model_ptr,
458 model_ptr->timing[index].first_unit,
459 model_ptr->timing[index].issue,
460 model_ptr->timing[index].done);
462 # Wait for a CR to become unbusy
463 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
467 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
470 cr_mask = (1 << cr_var);
471 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
472 TRACE(trace_model,("waiting for CR %d\n", cr_var));
473 model_ptr->nr_stalls_data++;
474 model_new_cycle(model_ptr);
477 # Schedule an instruction that takes integer input registers and produces output registers
478 void::model-function::ppc_insn_int:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
479 const unsigned32 int_mask = out_mask | in_mask;
480 model_busy *busy_ptr;
482 if ((model_ptr->int_busy & int_mask) != 0) {
483 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
485 while ((model_ptr->int_busy & int_mask) != 0) {
486 if (WITH_TRACE && ppc_trace[trace_model])
487 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
489 model_ptr->nr_stalls_data++;
490 model_new_cycle(model_ptr);
494 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
495 model_ptr->int_busy |= out_mask;
496 busy_ptr->int_busy |= out_mask;
497 if (WITH_TRACE && ppc_trace[trace_model])
498 model_trace_make_busy(model_ptr, out_mask, 0, 0);
500 # Schedule an instruction that takes integer input registers and produces output registers & sets some CR registers
501 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
502 const unsigned32 int_mask = out_mask | in_mask;
503 model_busy *busy_ptr;
505 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
506 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
508 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
509 if (WITH_TRACE && ppc_trace[trace_model])
510 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
512 model_ptr->nr_stalls_data++;
513 model_new_cycle(model_ptr);
517 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
518 model_ptr->int_busy |= out_mask;
519 busy_ptr->int_busy |= out_mask;
520 model_ptr->cr_fpscr_busy |= cr_mask;
521 busy_ptr->cr_fpscr_busy |= cr_mask;
522 if (WITH_TRACE && ppc_trace[trace_model])
523 model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
526 # Schedule an instruction that takes CR input registers and produces output CR registers
527 void::model-function::ppc_insn_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
528 const unsigned32 cr_mask = out_mask | in_mask;
529 model_busy *busy_ptr;
531 if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
532 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
534 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
535 if (WITH_TRACE && ppc_trace[trace_model])
536 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
538 model_ptr->nr_stalls_data++;
539 model_new_cycle(model_ptr);
543 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
544 model_ptr->cr_fpscr_busy |= out_mask;
545 busy_ptr->cr_fpscr_busy |= out_mask;
546 if (WITH_TRACE && ppc_trace[trace_model])
547 model_trace_make_busy(model_ptr, 0, 0, out_mask);
550 # Schedule an instruction that takes floating point input registers and produces output fp registers
551 void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
552 const unsigned32 fp_mask = out_mask | in_mask;
553 model_busy *busy_ptr;
555 if ((model_ptr->fp_busy & fp_mask) != 0) {
556 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
558 while ((model_ptr->fp_busy & fp_mask) != 0) {
559 if (WITH_TRACE && ppc_trace[trace_model])
560 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
562 model_ptr->nr_stalls_data++;
563 model_new_cycle(model_ptr);
567 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
568 model_ptr->fp_busy |= out_mask;
569 busy_ptr->fp_busy |= out_mask;
570 if (WITH_TRACE && ppc_trace[trace_model])
571 model_trace_make_busy(model_ptr, 0, out_mask, 0);
574 # Schedule an instruction that takes floating point input registers and produces output fp registers & sets some CR regs
575 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
576 const unsigned32 fp_mask = out_mask | in_mask;
577 model_busy *busy_ptr;
579 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
580 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
582 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
583 if (WITH_TRACE && ppc_trace[trace_model])
584 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
586 model_ptr->nr_stalls_data++;
587 model_new_cycle(model_ptr);
591 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
592 model_ptr->fp_busy |= out_mask;
593 busy_ptr->fp_busy |= out_mask;
594 model_ptr->cr_fpscr_busy |= cr_mask;
595 busy_ptr->cr_fpscr_busy |= cr_mask;
596 if (WITH_TRACE && ppc_trace[trace_model])
597 model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
600 # Schedule an instruction that takes both int/float input registers and produces output int/float registers
601 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
602 const unsigned32 int_mask = out_int_mask | in_int_mask;
603 const unsigned32 fp_mask = out_fp_mask | in_fp_mask;
604 model_busy *busy_ptr;
606 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
607 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
609 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
610 if (WITH_TRACE && ppc_trace[trace_model])
611 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
613 model_ptr->nr_stalls_data++;
614 model_new_cycle(model_ptr);
617 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
618 model_ptr->int_busy |= out_int_mask;
619 busy_ptr->int_busy |= out_int_mask;
620 model_ptr->fp_busy |= out_fp_mask;
621 busy_ptr->fp_busy |= out_fp_mask;
622 if (WITH_TRACE && ppc_trace[trace_model])
623 model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0);
627 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
628 void::model-function::ppc_insn_from_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
629 model_busy *busy_ptr;
631 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
632 if (WITH_TRACE && ppc_trace[trace_model])
633 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
635 model_ptr->nr_stalls_data++;
636 model_new_cycle(model_ptr);
639 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
640 model_ptr->int_busy |= int_mask;
641 busy_ptr->int_busy |= int_mask;
642 if (WITH_TRACE && ppc_trace[trace_model])
643 model_trace_make_busy(model_ptr, int_mask, 0, 0);
645 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
646 void::model-function::ppc_insn_to_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
647 model_busy *busy_ptr;
649 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
650 if (WITH_TRACE && ppc_trace[trace_model])
651 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
653 model_ptr->nr_stalls_data++;
654 model_new_cycle(model_ptr);
657 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
658 busy_ptr->spr_busy = nSPR;
659 model_ptr->spr_busy[nSPR] = 1;
660 TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));
662 # Schedule a MFCR instruction that moves the CR into an integer regsiter
663 void::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, unsigned32 int_mask
664 const unsigned32 cr_mask = 0xff;
665 model_busy *busy_ptr;
667 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
668 if (WITH_TRACE && ppc_trace[trace_model])
669 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
671 model_ptr->nr_stalls_data++;
672 model_new_cycle(model_ptr);
675 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
676 model_ptr->int_busy |= int_mask;
677 busy_ptr->int_busy |= int_mask;
678 if (WITH_TRACE && ppc_trace[trace_model])
679 model_trace_make_busy(model_ptr, int_mask, 0, 0);
681 # Schedule a MTCR instruction that moves an integer register into the CR
682 void::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, unsigned32 int_mask, unsigned FXM
685 unsigned32 cr_mask = 0;
686 const model_time *normal_time = &model_ptr->timing[index];
687 static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 };
688 model_busy *busy_ptr;
690 for (f = 0; f < 8; f++) {
691 if (FXM & (0x80 >> f)) {
697 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
698 if (WITH_TRACE && ppc_trace[trace_model])
699 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
701 model_ptr->nr_stalls_data++;
702 model_new_cycle(model_ptr);
705 /* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */
706 if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) {
707 normal_time = &ppc604_1bit_time;
710 busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
711 busy_ptr->cr_fpscr_busy |= cr_mask;
712 model_ptr->cr_fpscr_busy |= cr_mask;
713 model_ptr->nr_mtcrf_crs[nr_crs]++;
714 if (WITH_TRACE && ppc_trace[trace_model])
715 model_trace_make_busy(model_ptr, 0, 0, cr_mask);
717 model_data *::model-function::model_create:cpu *processor
718 model_data *model_ptr = ZALLOC(model_data);
719 ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
720 model_ptr->name = model_name[CURRENT_MODEL];
721 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
722 model_ptr->processor = processor;
723 model_ptr->nr_cycles = 1;
726 void::model-function::model_init:model_data *model_ptr
728 void::model-function::model_halt:model_data *model_ptr
729 /* Let pipeline drain */
730 while (model_ptr->busy_list)
731 model_new_cycle(model_ptr);
733 model_print *::model-function::model_mon_info:model_data *model_ptr
740 head = tail = ZALLOC(model_print);
741 tail->count = model_ptr->nr_cycles;
742 tail->name = "cycle";
743 tail->suffix_plural = "s";
744 tail->suffix_singular = "";
746 if (model_ptr->nr_stalls_data) {
747 tail->next = ZALLOC(model_print);
749 tail->count = model_ptr->nr_stalls_data;
750 tail->name = "stall";
751 tail->suffix_plural = "s waiting for data";
752 tail->suffix_singular = " waiting for data";
755 if (model_ptr->nr_stalls_unit) {
756 tail->next = ZALLOC(model_print);
758 tail->count = model_ptr->nr_stalls_unit;
759 tail->name = "stall";
760 tail->suffix_plural = "s waiting for a function unit";
761 tail->suffix_singular = " waiting for a function unit";
764 if (model_ptr->nr_stalls_serialize) {
765 tail->next = ZALLOC(model_print);
767 tail->count = model_ptr->nr_stalls_serialize;
768 tail->name = "stall";
769 tail->suffix_plural = "s waiting for serialization";
770 tail->suffix_singular = " waiting for serialization";
773 if (model_ptr->nr_branches) {
774 tail->next = ZALLOC(model_print);
776 tail->count = model_ptr->nr_branches;
777 tail->name = "branch";
778 tail->suffix_plural = "es";
779 tail->suffix_singular = "";
782 if (model_ptr->nr_branches_fallthrough) {
783 tail->next = ZALLOC(model_print);
785 tail->count = model_ptr->nr_branches_fallthrough;
786 tail->name = "conditional branch";
787 tail->suffix_plural = "es fell through";
788 tail->suffix_singular = " fell through";
791 if (model_ptr->nr_branch_predict_trues) {
792 tail->next = ZALLOC(model_print);
794 tail->count = model_ptr->nr_branch_predict_trues;
795 tail->name = "successful branch prediction";
796 tail->suffix_plural = "s";
797 tail->suffix_singular = "";
800 if (model_ptr->nr_branch_predict_falses) {
801 tail->next = ZALLOC(model_print);
803 tail->count = model_ptr->nr_branch_predict_falses;
804 tail->name = "unsuccessful branch prediction";
805 tail->suffix_plural = "s";
806 tail->suffix_singular = "";
809 for (j = 0; j < (sizeof(ppc_branch_conditional_name) / sizeof(ppc_branch_conditional_name[0])) ; j++) {
810 if (model_ptr->nr_branch_conditional[j]) {
811 tail->next = ZALLOC(model_print);
813 tail->count = model_ptr->nr_branch_conditional[j];
814 tail->name = ppc_branch_conditional_name[j];
815 tail->suffix_plural = " conditional branches";
816 tail->suffix_singular = " conditional branch";
820 for (j = 0; j < 9; j++) {
821 if (model_ptr->nr_mtcrf_crs[j]) {
822 tail->next = ZALLOC(model_print);
824 tail->count = model_ptr->nr_mtcrf_crs[j];
825 tail->name = ppc_nr_mtcrf_crs[j];
826 tail->suffix_plural = " instructions";
827 tail->suffix_singular = " instruction";
832 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
833 if (model_ptr->nr_units[i]) {
834 nr_insns += model_ptr->nr_units[i];
835 tail->next = ZALLOC(model_print);
837 tail->count = model_ptr->nr_units[i];
838 tail->name = ppc_function_unit_name[i];
839 tail->suffix_plural = "s";
840 tail->suffix_singular = "";
844 tail->next = ZALLOC(model_print);
846 tail->count = nr_insns;
847 tail->name = "instruction";
848 tail->suffix_plural = "s that were accounted for in timing info";
849 tail->suffix_singular = " that was accounted for in timing info";
851 tail->next = (model_print *)0;
854 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
856 model_print *next = ptr->next;
861 void::model-function::model_branches:model_data *model_ptr, int failed, int conditional
862 model_ptr->nr_units[PPC_UNIT_BPU]++;
864 model_ptr->nr_branches_fallthrough++;
866 model_ptr->nr_branches++;
867 if (conditional >= 0)
868 model_ptr->nr_branch_conditional[conditional]++;
869 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
871 void::model-function::model_branch_predict:model_data *model_ptr, int success
873 model_ptr->nr_branch_predict_trues++;
875 model_ptr->nr_branch_predict_falses++;
878 # The following (illegal) instruction is `known' by gen and is
879 # called when ever an illegal instruction is encountered
881 program_interrupt(processor, cia,
882 illegal_instruction_program_interrupt);
886 # The following (floating point unavailable) instruction is `known' by gen
887 # and is called when ever an a floating point instruction is to be
888 # executed but floating point is make unavailable by the MSR
889 ::internal::floating_point_unavailable
890 floating_point_unavailable_interrupt(processor, cia);
895 # Floating point support functions
898 # Convert 32bit single to 64bit double
899 unsigned64::function::DOUBLE:unsigned32 WORD
901 if (EXTRACTED32(WORD, 1, 8) > 0
902 && EXTRACTED32(WORD, 1, 8) < 255) {
903 /* normalized operand */
904 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
905 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
906 | INSERTED64(not_word_1_1, 2, 2)
907 | INSERTED64(not_word_1_1, 3, 3)
908 | INSERTED64(not_word_1_1, 4, 4)
909 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
911 else if (EXTRACTED32(WORD, 1, 8) == 0
912 && EXTRACTED32(WORD, 9, 31) != 0) {
913 /* denormalized operand */
914 int sign = EXTRACTED32(WORD, 0, 0);
916 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
917 /* normalize the operand */
918 while (MASKED64(frac, 0, 0) == 0) {
922 FRT = (INSERTED64(sign, 0, 0)
923 | INSERTED64(exp + 1023, 1, 11)
924 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
926 else if (EXTRACTED32(WORD, 1, 8) == 255
927 || EXTRACTED32(WORD, 1, 31) == 0) {
928 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
929 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
930 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
931 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
932 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
935 error("DOUBLE - unknown case\n");
940 # Convert 64bit single to 32bit double
941 unsigned32::function::SINGLE:unsigned64 FRS
943 if (EXTRACTED64(FRS, 1, 11) > 896
944 || EXTRACTED64(FRS, 1, 63) == 0) {
945 /* no denormalization required (includes Zero/Infinity/NaN) */
946 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
947 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
949 else if (874 <= EXTRACTED64(FRS, 1, 11)
950 && EXTRACTED64(FRS, 1, 11) <= 896) {
951 /* denormalization required */
952 int sign = EXTRACTED64(FRS, 0, 0);
953 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
954 unsigned64 frac = (BIT64(0)
955 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
956 /* denormalize the operand */
958 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
961 WORD = (INSERTED32(sign, 0, 0)
962 | INSERTED32(0x00, 1, 8)
963 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
966 WORD = 0x0; /* ??? */
971 # round 64bit double to 64bit but single
972 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
973 /* comparisons ignore u bits */
976 int lsb = EXTRACTED64(*frac_grx, 23, 23);
977 int gbit = EXTRACTED64(*frac_grx, 24, 24);
978 int rbit = EXTRACTED64(*frac_grx, 25, 25);
979 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
980 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
981 if (lsb == 1 && gbit == 1) inc = 1;
982 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
983 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
985 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
986 if (sign == 0 && gbit == 1) inc = 1;
987 if (sign == 0 && rbit == 1) inc = 1;
988 if (sign == 0 && xbit == 1) inc = 1;
990 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
991 if (sign == 1 && gbit == 1) inc = 1;
992 if (sign == 1 && rbit == 1) inc = 1;
993 if (sign == 1 && xbit == 1) inc = 1;
995 /* work out addition in low 25 bits of out */
996 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
997 *frac_grx = INSERTED64(out, 0, 23);
998 if (out & BIT64(64 - 23 - 1 - 1)) {
999 *frac_grx = (BIT64(0) |
1000 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
1003 /* frac_grx[24:52] = 0 already */
1005 FPSCR_SET_FI(gbit || rbit || xbit);
1009 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
1011 if (round_mode == fpscr_rn_round_to_nearest) {
1012 if (*frac64 == 1 && gbit == 1) inc = 1;
1013 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
1014 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
1016 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1017 if (sign == 0 && gbit == 1) inc = 1;
1018 if (sign == 0 && rbit == 1) inc = 1;
1019 if (sign == 0 && xbit == 1) inc = 1;
1021 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1022 if (sign == 1 && gbit == 1) inc = 1;
1023 if (sign == 1 && rbit == 1) inc = 1;
1024 if (sign == 1 && xbit == 1) inc = 1;
1026 /* frac[0:64] = frac[0:64} + inc */
1027 *frac += (*frac64 && inc ? 1 : 0);
1028 *frac64 = (*frac64 + inc) & 0x1;
1030 FPSCR_SET_FI(gbit | rbit | xbit);
1033 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
1036 int lsb = EXTRACTED64(*frac, 52, 52);
1037 int gbit = EXTRACTED64(*frac, 53, 53);
1038 int rbit = EXTRACTED64(*frac, 54, 54);
1039 int xbit = EXTRACTED64(*frac, 55, 55);
1040 if (round_mode == fpscr_rn_round_to_nearest) {
1041 if (lsb == 1 && gbit == 1) inc = 1;
1042 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1043 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1045 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1046 if (sign == 0 && gbit == 1) inc = 1;
1047 if (sign == 0 && rbit == 1) inc = 1;
1048 if (sign == 0 && xbit == 1) inc = 1;
1050 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1051 if (sign == 1 && gbit == 1) inc = 1;
1052 if (sign == 1 && rbit == 1) inc = 1;
1053 if (sign == 1 && xbit == 1) inc = 1;
1055 /* frac//carry_out = frac + inc */
1056 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1057 carry_out = EXTRACTED64(*frac, 0, 0);
1059 if (carry_out == 1) *exp = *exp + 1;
1061 FPSCR_SET_FI(gbit | rbit | xbit);
1062 FPSCR_SET_XX(FPSCR & fpscr_fi);
1065 # conversion of FP to integer
1066 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
1069 unsigned64 frac = 0;
1074 int sign = EXTRACTED64(frb, 0, 0);
1075 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1076 goto Infinity_Operand;
1077 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1079 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1081 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
1082 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1083 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1084 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1085 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1088 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1089 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1092 gbit = 0, rbit = 0, xbit = 0;
1093 for (i = 1; i <= 63 - exp; i++) {
1097 frac64 = EXTRACTED64(frac, 63, 63);
1098 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1100 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1101 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1104 frac += (frac64 ? 1 : 0);
1105 frac64 = (frac64 + 1) & 0x1;
1107 if (tgt_precision == 32 /* can ignore frac64 in compare */
1108 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1110 if (tgt_precision == 64 /* can ignore frac64 in compare */
1111 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1113 if (tgt_precision == 32 /* can ignore frac64 in compare */
1114 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1116 if (tgt_precision == 64 /* can ignore frac64 in compare */
1117 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1119 FPSCR_SET_XX(FPSCR & fpscr_fi);
1120 if (tgt_precision == 32)
1121 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1122 if (tgt_precision == 64)
1123 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1124 /*FPSCR[fprf] = undefined */
1130 FPSCR_OR_VX(fpscr_vxcvi);
1131 if ((FPSCR & fpscr_ve) == 0) {
1132 if (tgt_precision == 32) {
1133 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1134 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1137 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1138 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1140 /* FPSCR[FPRF] = undefined */
1147 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1148 if ((FPSCR & fpscr_ve) == 0) {
1149 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1150 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1151 /* FPSCR[fprf] = undefined */
1158 FPSCR_OR_VX(fpscr_vxcvi);
1159 if ((FPSCR & fpscr_ve) == 0) {
1160 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1161 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1162 /* FPSCR[fprf] = undefined */
1169 FPSCR_OR_VX(fpscr_vxcvi);
1170 if ((FPSCR & fpscr_ve) == 0) {
1171 if (tgt_precision == 32) {
1172 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1173 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1176 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1177 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1179 /* FPSCR[fprf] = undefined */
1185 # extract out raw fields of a FP number
1186 int::function::sign:unsigned64 FRS
1187 return (MASKED64(FRS, 0, 0)
1190 int::function::biased_exp:unsigned64 frs, int single
1192 return EXTRACTED64(frs, 1, 8);
1194 return EXTRACTED64(frs, 1, 11);
1195 unsigned64::function::fraction:unsigned64 frs, int single
1197 return EXTRACTED64(frs, 9, 31);
1199 return EXTRACTED64(frs, 12, 63);
1201 # a number?, each of the below return +1 or -1 (based on sign bit)
1203 int::function::is_nor:unsigned64 frs, int single
1204 int exp = biased_exp(frs, single);
1206 && exp <= (single ? 254 : 2046));
1207 int::function::is_zero:unsigned64 FRS
1208 return (MASKED64(FRS, 1, 63) == 0
1211 int::function::is_den:unsigned64 frs, int single
1212 int exp = biased_exp(frs, single);
1213 unsigned64 frac = fraction(frs, single);
1214 return (exp == 0 && frac != 0
1217 int::function::is_inf:unsigned64 frs, int single
1218 int exp = biased_exp(frs, single);
1219 int frac = fraction(frs, single);
1220 return (exp == (single ? 255 : 2047) && frac == 0
1223 int::function::is_NaN:unsigned64 frs, int single
1224 int exp = biased_exp(frs, single);
1225 int frac = fraction(frs, single);
1226 return (exp == (single ? 255 : 2047) && frac != 0
1229 int::function::is_SNaN:unsigned64 frs, int single
1230 return (is_NaN(frs, single)
1231 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1234 int::function::is_QNaN:unsigned64 frs, int single
1235 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1236 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1237 return *(double*)fra < *(double*)frb;
1238 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1239 return *(double*)fra > *(double*)frb;
1240 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1241 return *(double*)fra == *(double*)frb;
1244 # which quiet nan should become the result
1245 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1247 if (is_NaN(fra, single))
1249 else if (is_NaN(frb, single))
1250 if (instruction_is_frsp)
1251 frt = MASKED64(frb, 0, 34);
1254 else if (is_NaN(frc, single))
1256 else if (generate_qnan)
1257 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1259 error("select_qnan - default reached\n");
1263 # detect invalid operation
1264 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1266 if ((check & fpscr_vxsnan)
1267 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1268 FPSCR_OR_VX(fpscr_vxsnan);
1271 if ((check & fpscr_vxisi)
1272 && (is_inf(fra, single) && is_inf(frb, single))
1273 && ((negate && sign(fra) != sign(frb))
1274 || (!negate && sign(fra) == sign(frb)))) {
1275 /*FIXME: don't handle inf-inf VS inf+-inf */
1276 FPSCR_OR_VX(fpscr_vxisi);
1279 if ((check & fpscr_vxidi)
1280 && (is_inf(fra, single) && is_inf(frb, single))) {
1281 FPSCR_OR_VX(fpscr_vxidi);
1284 if ((check & fpscr_vxzdz)
1285 && (is_zero(fra) && is_zero(frb))) {
1286 FPSCR_OR_VX(fpscr_vxzdz);
1289 if ((check & fpscr_vximz)
1290 && (is_zero(fra) && is_inf(frb, single))) {
1291 FPSCR_OR_VX(fpscr_vximz);
1294 if ((check & fpscr_vxvc)
1295 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1296 FPSCR_OR_VX(fpscr_vxvc);
1299 if ((check & fpscr_vxsoft)) {
1300 FPSCR_OR_VX(fpscr_vxsoft);
1303 if ((check & fpscr_vxsqrt)
1305 FPSCR_OR_VX(fpscr_vxsqrt);
1308 /* if ((check && fpscr_vxcvi) {
1309 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1310 FPSCR_OR_VX(fpscr_vxcvi);
1320 # handle case of invalid operation
1321 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
1322 if (FPSCR & fpscr_ve) {
1323 /* invalid operation exception enabled */
1327 /* fpscr_FPRF unchanged */
1330 /* invalid operation exception disabled */
1331 if (instruction_is_convert_to_64bit) {
1334 else if (instruction_is_convert_to_32bit) {
1337 else { /* arrith, frsp */
1338 *frt = select_qnan(fra, frb, frc,
1339 instruction_is_frsp, 0/*generate*/, single);
1342 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1350 # I.2.4.1 Branch Instructions
1352 0.18,6.LI,30.AA,31.LK:I:t::Branch
1353 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1354 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1355 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1356 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1357 if (AA) NIA = IEA(EXTS(LI_0b00));
1358 else NIA = IEA(CIA + EXTS(LI_0b00));
1359 if (LK) LR = (spreg)CIA+4;
1360 if (WITH_MODEL_ISSUE)
1361 model_branches(cpu_model(processor), 1, -1);
1363 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
1364 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1365 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1366 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1367 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1368 int M, ctr_ok, cond_ok, succeed;
1369 if (WITH_MODEL_ISSUE && ! BO{0})
1370 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1371 if (is_64bit_implementation && is_64bit_mode) M = 0;
1373 if (!BO{2}) CTR = CTR - 1;
1374 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1375 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1376 if (ctr_ok && cond_ok) {
1377 if (AA) NIA = IEA(EXTS(BD_0b00));
1378 else NIA = IEA(CIA + EXTS(BD_0b00));
1383 if (LK) LR = (spreg)IEA(CIA + 4);
1384 if (WITH_MODEL_ISSUE)
1385 model_branches(cpu_model(processor), succeed, BO);
1388 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1389 reverse = EXTS(BD_0b00) < 0;
1390 } else { /* branch prediction bit not set */
1391 reverse = EXTS(BD_0b00) >= 0;
1393 if (WITH_MODEL_ISSUE)
1394 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1397 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
1398 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1399 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1400 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1401 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1402 int M, ctr_ok, cond_ok, succeed;
1403 if (is_64bit_implementation && is_64bit_mode) M = 0;
1405 if (WITH_MODEL_ISSUE && ! BO{0})
1406 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1407 if (!BO{2}) CTR = CTR - 1;
1408 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1409 cond_ok = BO{0} || (CR{BI} == BO{1});
1410 if (ctr_ok && cond_ok) {
1416 if (LK) LR = (spreg)IEA(CIA + 4);
1417 if (WITH_MODEL_ISSUE) {
1418 model_branches(cpu_model(processor), succeed, BO);
1420 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1423 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
1424 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1425 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1426 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1427 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1428 int cond_ok, succeed;
1429 if (WITH_MODEL_ISSUE && ! BO{0})
1430 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1431 cond_ok = BO{0} || (CR{BI} == BO{1});
1433 NIA = IEA(CTR_0b00);
1438 if (LK) LR = (spreg)IEA(CIA + 4);
1439 if (WITH_MODEL_ISSUE) {
1440 model_branches(cpu_model(processor), succeed, BO);
1442 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1446 # I.2.4.2 System Call Instruction
1448 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
1449 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1450 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1451 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1452 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1453 if (WITH_MODEL_ISSUE)
1454 model_serialize(my_index, cpu_model(processor));
1455 system_call_interrupt(processor, cia);
1458 # I.2.4.3 Condition Register Logical Instructions
1460 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1461 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1462 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1463 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1464 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1465 BLIT32(CR, BT, CR{BA} && CR{BB});
1466 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1468 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1469 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1470 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1471 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1472 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1473 BLIT32(CR, BT, CR{BA} || CR{BB});
1474 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1476 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1477 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1478 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1479 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1480 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1481 BLIT32(CR, BT, CR{BA} != CR{BB});
1482 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1484 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1485 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1486 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1487 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1488 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1489 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1490 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1492 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1493 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1494 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1495 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1496 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1497 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1498 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1500 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1501 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1502 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1503 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1504 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1505 BLIT32(CR, BT, CR{BA} == CR{BB});
1506 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1508 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1509 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1510 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1511 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1512 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1513 BLIT32(CR, BT, CR{BA} && !CR{BB});
1514 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1516 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1517 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1518 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1519 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1520 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1521 BLIT32(CR, BT, CR{BA} || !CR{BB});
1522 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1525 # I.2.4.4 Condition Register Field Instruction
1527 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1528 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1529 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1530 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1531 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1532 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1533 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
1537 # I.3.3.2 Fixed-Point Load Instructions
1540 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1541 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1542 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1543 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1544 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1550 *rT = MEM(unsigned, EA, 1);
1551 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1554 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1555 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1556 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1557 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1558 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1564 *rT = MEM(unsigned, EA, 1);
1565 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1567 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1568 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1569 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1570 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1571 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1573 if (RA == 0 || RA == RT)
1574 program_interrupt(processor, cia,
1575 illegal_instruction_program_interrupt);
1577 *rT = MEM(unsigned, EA, 1);
1579 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1581 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1582 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1583 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1584 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1585 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1587 if (RA == 0 || RA == RT)
1588 program_interrupt(processor, cia,
1589 illegal_instruction_program_interrupt);
1591 *rT = MEM(unsigned, EA, 1);
1593 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1595 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1596 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1597 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1598 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1599 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1605 *rT = MEM(unsigned, EA, 2);
1606 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1608 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1609 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1610 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1611 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1612 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1618 *rT = MEM(unsigned, EA, 2);
1619 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1621 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1622 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1623 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1624 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1625 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1627 if (RA == 0 || RA == RT)
1628 program_interrupt(processor, cia,
1629 illegal_instruction_program_interrupt);
1631 *rT = MEM(unsigned, EA, 2);
1633 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1635 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1636 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1637 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1638 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1639 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1641 if (RA == 0 || RA == RT)
1642 program_interrupt(processor, cia,
1643 illegal_instruction_program_interrupt);
1645 *rT = MEM(unsigned, EA, 2);
1647 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1649 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1650 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1651 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1652 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1653 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1659 *rT = MEM(signed, EA, 2);
1660 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1662 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1663 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1664 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1665 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1666 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1672 *rT = MEM(signed, EA, 2);
1673 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1675 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1676 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1677 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1678 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1679 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1681 if (RA == 0 || RA == RT)
1682 program_interrupt(processor, cia,
1683 illegal_instruction_program_interrupt);
1685 *rT = MEM(signed, EA, 2);
1686 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1688 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1689 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1690 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1691 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1692 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1694 if (RA == 0 || RA == RT)
1695 program_interrupt(processor, cia,
1696 illegal_instruction_program_interrupt);
1698 *rT = MEM(signed, EA, 2);
1700 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1702 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1703 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1704 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1705 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1706 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1712 *rT = MEM(unsigned, EA, 4);
1713 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1715 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1716 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1717 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1718 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1719 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1725 *rT = MEM(unsigned, EA, 4);
1726 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1728 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1729 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1730 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1731 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1732 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1734 if (RA == 0 || RA == RT)
1735 program_interrupt(processor, cia,
1736 illegal_instruction_program_interrupt);
1738 *rT = MEM(unsigned, EA, 4);
1740 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1742 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1743 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1744 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1745 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1746 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1748 if (RA == 0 || RA == RT)
1749 program_interrupt(processor, cia,
1750 illegal_instruction_program_interrupt);
1752 *rT = MEM(unsigned, EA, 4);
1754 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1756 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1759 # if (RA == 0) b = 0;
1761 # EA = b + EXTS(DS_0b00);
1762 # *rT = MEM(signed, EA, 4);
1764 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1767 # if (RA == 0) b = 0;
1770 # *rT = MEM(signed, EA, 4);
1772 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1774 # if (RA == 0 || RA == RT)
1775 # program_interrupt(processor, cia
1776 # illegal_instruction_program_interrupt);
1778 # *rT = MEM(signed, EA, 4);
1781 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1784 # if (RA == 0) b = 0;
1786 # EA = b + EXTS(DS_0b00);
1787 # *rT = MEM(unsigned, EA, 8);
1789 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1792 # if (RA == 0) b = 0;
1795 # *rT = MEM(unsigned, EA, 8);
1797 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1799 # if (RA == 0 || RA == RT)
1800 # program_interrupt(processor, cia
1801 # illegal_instruction_program_interrupt);
1802 # EA = *rA + EXTS(DS_0b00);
1803 # *rT = MEM(unsigned, EA, 8);
1806 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1808 # if (RA == 0 || RA == RT)
1809 # program_interrupt(processor, cia
1810 # illegal_instruction_program_interrupt);
1812 # *rT = MEM(unsigned, EA, 8);
1818 # I.3.3.3 Fixed-Point Store Instructions
1821 0.38,6.RS,11.RA,16.D:D:::Store Byte
1822 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1823 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1824 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1825 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1832 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1834 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1835 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1836 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1837 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1838 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1845 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1847 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1848 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1849 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1850 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1851 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1854 program_interrupt(processor, cia,
1855 illegal_instruction_program_interrupt);
1859 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1861 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1862 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1863 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1864 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1865 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1868 program_interrupt(processor, cia,
1869 illegal_instruction_program_interrupt);
1873 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1875 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1876 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1877 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1878 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1879 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1886 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1888 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1889 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1890 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1891 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1892 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1899 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1901 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1902 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1903 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1904 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1905 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1908 program_interrupt(processor, cia,
1909 illegal_instruction_program_interrupt);
1913 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1915 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1916 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1917 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1918 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1919 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1922 program_interrupt(processor, cia,
1923 illegal_instruction_program_interrupt);
1927 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1929 0.36,6.RS,11.RA,16.D:D:::Store Word
1930 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1931 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1932 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1933 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1940 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1942 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
1943 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1944 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1945 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1946 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1953 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1955 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
1956 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1957 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1958 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1959 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1962 program_interrupt(processor, cia,
1963 illegal_instruction_program_interrupt);
1967 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1969 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
1970 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1971 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1972 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1973 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1976 program_interrupt(processor, cia,
1977 illegal_instruction_program_interrupt);
1981 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1983 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
1986 # if (RA == 0) b = 0;
1988 # EA = b + EXTS(DS_0b00);
1989 # STORE(EA, 8, *rS);
1990 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
1993 # if (RA == 0) b = 0;
1996 # STORE(EA, 8, *rS);
1997 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2000 # program_interrupt(processor, cia
2001 # illegal_instruction_program_interrupt);
2002 # EA = *rA + EXTS(DS_0b00);
2003 # STORE(EA, 8, *rS);
2005 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2008 # program_interrupt(processor, cia
2009 # illegal_instruction_program_interrupt);
2011 # STORE(EA, 8, *rS);
2016 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2019 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2020 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2021 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2022 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2023 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2029 *rT = SWAP_2(MEM(unsigned, EA, 2));
2030 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2032 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2033 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2034 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2035 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2036 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2042 *rT = SWAP_4(MEM(unsigned, EA, 4));
2043 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2045 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2046 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2047 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2048 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2049 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2055 STORE(EA, 2, SWAP_2(*rS));
2056 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2058 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2059 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2060 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2061 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2062 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2068 STORE(EA, 4, SWAP_4(*rS));
2069 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2073 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2076 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
2078 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2082 # I.3.3.6 Fixed-Point Move Assist Instructions
2085 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
2087 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2089 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
2091 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2095 # I.3.3.7 Storage Synchronization Instructions
2097 # HACK: Rather than monitor addresses looking for a reason
2098 # to cancel a reservation. This code instead keeps
2099 # a copy of the data read from memory. Before performing
2100 # a store, the memory area is checked to see if it has
2102 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2103 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2104 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2105 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2106 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2113 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2114 RESERVE_DATA = MEM(unsigned, EA, 4);
2116 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2118 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2125 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2126 RESERVE_DATA = MEM(unsigned, EA, 8);
2128 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2130 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2131 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2132 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2133 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2134 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2141 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2142 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2144 CR_SET_XER_SO(0, cr_i_zero);
2147 /* ment to randomly to store, we never do! */
2148 CR_SET_XER_SO(0, 0);
2153 CR_SET_XER_SO(0, 0);
2155 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2157 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2164 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2165 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2167 CR_SET_XER_SO(0, cr_i_zero);
2170 /* ment to randomly to store, we never do */
2171 CR_SET_XER_SO(0, 0);
2176 CR_SET_XER_SO(0, 0);
2178 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2180 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2181 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2182 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2183 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2184 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2189 # I.3.3.9 Fixed-Point Arithmetic Instructions
2192 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
2193 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2194 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2195 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2196 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2197 if (RA_is_0) *rT = EXTS(SI);
2198 else *rT = *rA + EXTS(SI);
2199 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2201 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2202 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2203 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2204 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2205 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2206 if (RA_is_0) *rT = EXTS(SI) << 16;
2207 else *rT = *rA + (EXTS(SI) << 16);
2208 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2210 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2211 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2212 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2213 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2214 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2217 ALU_END(*rT, 0/*CA*/, OE, Rc);
2218 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2220 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2221 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2222 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2223 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2224 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2229 ALU_END(*rT, 0/*CA*/, OE, Rc);
2230 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2232 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2233 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2234 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2235 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2236 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2239 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2240 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2242 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2243 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2244 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2245 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2246 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2249 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2250 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
2252 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2253 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2254 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2255 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2256 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2261 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2262 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2264 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
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_IU, 1, 1, 0
2268 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2271 ALU_END(*rT, 1/*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.8,31.Rc:XO:::Subtract From Carrying
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
2279 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2284 ALU_END(*rT, 1/*CA*/, OE, Rc);
2285 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2287 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2288 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2289 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2290 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2291 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2295 ALU_END(*rT, 1/*CA*/, OE, Rc);
2296 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2298 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2299 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2300 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2301 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2302 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2307 ALU_END(*rT, 1/*CA*/, OE, Rc);
2308 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2310 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2311 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2312 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2313 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2314 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2318 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2320 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2321 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2322 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2323 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2324 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2329 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2331 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2332 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2333 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2334 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2335 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2338 ALU_END(*rT, 1/*CA*/, OE, Rc);
2339 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2341 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero 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, Rc);
2352 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
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
2360 ALU_END(*rT,0/*CA*/,OE,Rc);
2361 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2363 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2364 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2365 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2366 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2367 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2368 signed_word prod = *rA * EXTS(SI);
2370 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2372 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2374 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2375 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2376 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2377 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2378 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2379 signed64 a = (signed32)(*rA);
2380 signed64 b = (signed32)(*rB);
2381 signed64 prod = a * b;
2382 signed_word t = prod;
2384 if (t != prod && OE)
2385 XER |= (xer_overflow | xer_summary_overflow);
2386 CR0_COMPARE(t, 0, Rc);
2387 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2389 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2391 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2392 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2393 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2394 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2395 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2396 signed64 a = (signed32)(*rA);
2397 signed64 b = (signed32)(*rB);
2398 signed64 prod = a * b;
2399 signed_word t = EXTRACTED64(prod, 0, 31);
2401 CR0_COMPARE(t, 0, Rc);
2402 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2404 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2406 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2407 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2408 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2409 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2410 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2411 unsigned64 a = (unsigned32)(*rA);
2412 unsigned64 b = (unsigned32)(*rB);
2413 unsigned64 prod = a * b;
2414 signed_word t = EXTRACTED64(prod, 0, 31);
2416 CR0_COMPARE(t, 0, Rc);
2417 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2419 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2421 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2422 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2423 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2424 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2425 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2426 signed64 dividend = (signed32)(*rA);
2427 signed64 divisor = (signed32)(*rB);
2428 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2429 || (dividend == 0x80000000 && divisor == -1)) {
2431 XER |= (xer_overflow | xer_summary_overflow);
2432 CR0_COMPARE(0, 0, Rc);
2435 signed64 quotent = dividend / divisor;
2437 CR0_COMPARE((signed_word)quotent, 0, Rc);
2439 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2441 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2443 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2444 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2445 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2446 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2447 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2448 unsigned64 dividend = (unsigned32)(*rA);
2449 unsigned64 divisor = (unsigned32)(*rB);
2452 XER |= (xer_overflow | xer_summary_overflow);
2453 CR0_COMPARE(0, 0, Rc);
2456 unsigned64 quotent = dividend / divisor;
2458 CR0_COMPARE((signed_word)quotent, 0, Rc);
2460 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2464 # I.3.3.10 Fixed-Point Compare Instructions
2467 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2468 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2469 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2470 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2471 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2472 if (!is_64bit_mode && L)
2473 program_interrupt(processor, cia,
2474 illegal_instruction_program_interrupt);
2477 signed_word b = EXTS(SI);
2482 CR_COMPARE(BF, a, b);
2484 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2486 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2487 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2488 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2489 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2490 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2491 if (!is_64bit_mode && L)
2492 program_interrupt(processor, cia,
2493 illegal_instruction_program_interrupt);
2505 CR_COMPARE(BF, a, b);
2507 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2509 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2510 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2511 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2512 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2513 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2514 if (!is_64bit_mode && L)
2515 program_interrupt(processor, cia,
2516 illegal_instruction_program_interrupt);
2519 unsigned_word b = UI;
2521 a = MASKED(*rA, 32, 63);
2524 CR_COMPARE(BF, a, b);
2526 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2528 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2529 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2530 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2531 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2532 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2533 if (!is_64bit_mode && L)
2534 program_interrupt(processor, cia,
2535 illegal_instruction_program_interrupt);
2540 a = MASKED(*rA, 32, 63);
2541 b = MASKED(*rB, 32, 63);
2547 CR_COMPARE(BF, a, b);
2549 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2553 # I.3.3.11 Fixed-Point Trap Instructions
2556 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2558 program_interrupt(processor, cia,
2559 illegal_instruction_program_interrupt);
2561 signed_word a = *rA;
2562 signed_word b = EXTS(SI);
2563 if ((a < b && TO{0})
2565 || (a == b && TO{2})
2566 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2567 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2569 program_interrupt(processor, cia,
2570 trap_program_interrupt);
2573 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2574 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2575 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2576 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2577 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2578 signed_word a = EXTENDED(*rA);
2579 signed_word b = EXTS(SI);
2580 if ((a < b && TO{0})
2582 || (a == b && TO{2})
2583 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2584 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2586 program_interrupt(processor, cia,
2587 trap_program_interrupt);
2589 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2591 program_interrupt(processor, cia,
2592 illegal_instruction_program_interrupt);
2594 signed_word a = *rA;
2595 signed_word b = *rB;
2596 if ((a < b && TO{0})
2598 || (a == b && TO{2})
2599 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2600 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2602 program_interrupt(processor, cia,
2603 trap_program_interrupt);
2606 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2607 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2608 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2609 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2610 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2611 signed_word a = EXTENDED(*rA);
2612 signed_word b = EXTENDED(*rB);
2613 if (TO == 12 && rA == rB) {
2614 ITRACE(trace_breakpoint, ("breakpoint\n"));
2615 cpu_halt(processor, cia, was_trap, 0);
2617 else if ((a < b && TO{0})
2619 || (a == b && TO{2})
2620 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2621 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2623 program_interrupt(processor, cia,
2624 trap_program_interrupt);
2627 # I.3.3.12 Fixed-Point Logical Instructions
2630 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2631 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2632 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2633 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2634 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2636 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2637 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2639 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2640 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2641 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2642 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2643 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2644 *rA = *rS & (UI << 16);
2645 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2646 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2648 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2649 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2650 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2651 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2652 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2654 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2656 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2657 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2658 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2659 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2660 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2661 *rA = *rS | (UI << 16);
2662 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2664 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2665 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2666 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2667 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2668 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2670 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2672 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2673 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2674 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2675 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2676 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2677 *rA = *rS ^ (UI << 16);
2678 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2680 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
2681 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2682 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2683 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2684 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2686 CR0_COMPARE(*rA, 0, Rc);
2687 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2689 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
2690 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2691 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2692 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2693 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2695 CR0_COMPARE(*rA, 0, Rc);
2696 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2698 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
2699 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2700 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2701 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2702 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2704 CR0_COMPARE(*rA, 0, Rc);
2705 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2707 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
2708 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2709 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2710 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2711 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2713 CR0_COMPARE(*rA, 0, Rc);
2714 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2716 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
2717 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2718 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2719 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2720 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2722 CR0_COMPARE(*rA, 0, Rc);
2723 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2725 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
2726 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2727 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2728 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2729 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2730 # *rA = ~(*rS ^ *rB); /* A === B */
2731 # CR0_COMPARE(*rA, 0, Rc);
2733 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
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
2739 CR0_COMPARE(*rA, 0, Rc);
2740 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2742 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
2743 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2744 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2745 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2746 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2748 CR0_COMPARE(*rA, 0, Rc);
2749 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2751 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
2752 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2753 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2754 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2755 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2756 *rA = (signed_word)(signed8)*rS;
2757 CR0_COMPARE(*rA, 0, Rc);
2758 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2760 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
2761 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2762 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2763 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2764 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2765 *rA = (signed_word)(signed16)*rS;
2766 CR0_COMPARE(*rA, 0, Rc);
2767 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2769 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2770 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2771 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2772 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2773 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2774 # *rA = (signed_word)(signed32)*rS;
2775 # CR0_COMPARE(*rA, 0, Rc);
2777 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2779 # unsigned64 mask = BIT64(0);
2780 # unsigned64 source = *rS;
2781 # while (!(source & mask) && mask != 0) {
2786 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2788 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
2789 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2790 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2791 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2792 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2794 unsigned32 mask = BIT32(0);
2795 unsigned32 source = *rS;
2796 while (!(source & mask) && mask != 0) {
2801 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2805 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2808 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
2809 # long n = (sh_5 << 4) | sh_0_4;
2810 # unsigned_word r = ROTL64(*rS, n);
2811 # long b = (mb_5 << 4) | mb_0_4;
2812 # unsigned_word m = MASK(b, 63);
2813 # signed_word result = r & m;
2815 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2817 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
2818 # long n = (sh_5 << 4) | sh_0_4;
2819 # unsigned_word r = ROTL64(*rS, n);
2820 # long e = (me_5 << 4) | me_0_4;
2821 # unsigned_word m = MASK(0, e);
2822 # signed_word result = r & m;
2824 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2826 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
2827 # long n = (sh_5 << 4) | sh_0_4;
2828 # unsigned_word r = ROTL64(*rS, n);
2829 # long b = (mb_5 << 4) | mb_0_4;
2830 # unsigned_word m = MASK(0, (64-n));
2831 # signed_word result = r & m;
2833 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2835 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2836 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2837 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2838 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2839 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2842 unsigned32 r = ROTL32(s, n);
2843 unsigned32 m = MASK(MB+32, ME+32);
2844 signed_word result = r & m;
2846 CR0_COMPARE(result, 0, Rc);
2848 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
2849 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
2850 (unsigned long)result, (unsigned long)CR));
2851 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2853 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2854 # long n = MASKED(*rB, 58, 63);
2855 # unsigned_word r = ROTL64(*rS, n);
2856 # long b = (mb_5 << 4) | mb_0_4;
2857 # unsigned_word m = MASK(b, 63);
2858 # signed_word result = r & m;
2860 # CR0_COMPARE(result, 0, Rc);
2862 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2863 # long n = MASKED(*rB, 58, 63);
2864 # unsigned_word r = ROTL64(*rS, n);
2865 # long e = (me_5 << 4) | me_0_4;
2866 # unsigned_word m = MASK(0, e);
2867 # signed_word result = r & m;
2869 # CR0_COMPARE(result, 0, Rc);
2871 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2872 # long n = MASKED(*rB, 59, 63);
2873 # unsigned32 r = ROTL32(*rS, n);
2874 # unsigned32 m = MASK(MB+32, ME+32);
2875 # signed_word result = r & m;
2877 # CR0_COMPARE(result, 0, Rc);
2879 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
2880 # long n = (sh_5 << 4) | sh_0_4;
2881 # unsigned_word r = ROTL64(*rS, n);
2882 # long b = (mb_5 << 4) | mb_0_4;
2883 # unsigned_word m = MASK(b, (64-n));
2884 # signed_word result = (r & m) | (*rA & ~m)
2886 # CR0_COMPARE(result, 0, Rc);
2888 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2889 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2890 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2891 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2892 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2894 unsigned32 r = ROTL32(*rS, n);
2895 unsigned32 m = MASK(MB+32, ME+32);
2896 signed_word result = (r & m) | (*rA & ~m);
2898 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
2899 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
2900 (unsigned long)result));
2901 CR0_COMPARE(result, 0, Rc);
2902 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2905 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2907 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2908 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2909 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2910 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2911 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2912 int n = MASKED(*rB, 59, 63);
2913 unsigned32 source = *rS;
2914 signed_word shifted;
2916 shifted = (source << n);
2920 CR0_COMPARE(shifted, 0, Rc);
2922 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2923 n, (unsigned long)source, (unsigned long)shifted));
2924 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2926 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
2928 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
2929 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2930 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2931 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2932 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2933 int n = MASKED(*rB, 59, 63);
2934 unsigned32 source = *rS;
2935 signed_word shifted;
2937 shifted = (source >> n);
2941 CR0_COMPARE(shifted, 0, Rc);
2943 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2944 n, (unsigned long)source, (unsigned long)shifted));
2945 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2947 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
2949 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
2950 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2951 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2952 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2953 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2955 signed_word r = ROTL32(*rS, /*64*/32-n);
2956 signed_word m = MASK(n+32, 63);
2957 int S = MASKED(*rS, 32, 32);
2958 signed_word shifted = (r & m) | (S ? ~m : 0);
2960 if (S && ((r & ~m) & MASK(32, 63)) != 0)
2964 CR0_COMPARE(shifted, 0, Rc);
2965 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2967 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
2969 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
2970 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2971 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2972 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2973 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2974 int n = MASKED(*rB, 58, 63);
2975 int shift = (n >= 31 ? 31 : n);
2976 signed32 source = (signed32)*rS; /* signed to keep sign bit */
2977 signed32 shifted = source >> shift;
2978 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
2979 *rA = (signed_word)shifted; /* if 64bit will sign extend */
2980 if (source < 0 && (source & mask))
2984 CR0_COMPARE(shifted, 0, Rc);
2985 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2988 # I.3.3.14 Move to/from System Register Instructions
2991 0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
2992 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2993 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2994 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2995 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
2996 int n = (SPR{5:9} << 5) | SPR{0:4};
2997 if (SPR{0} && IS_PROBLEM_STATE(processor))
2998 program_interrupt(processor, cia,
2999 privileged_instruction_program_interrupt);
3000 else if (!spr_is_valid(n)
3001 || spr_is_readonly(n))
3002 program_interrupt(processor, cia,
3003 illegal_instruction_program_interrupt);
3005 spreg new_val = (spr_length(n) == 64
3007 : MASKED(*rS, 32, 63));
3008 /* HACK - time base registers need to be updated immediatly */
3009 if (WITH_TIME_BASE) {
3012 cpu_set_time_base(processor,
3013 (MASKED64(cpu_get_time_base(processor), 32, 63)
3014 | INSERTED64(new_val, 0, 31)));
3017 cpu_set_time_base(processor,
3018 (MASKED64(cpu_get_time_base(processor), 0, 31)
3019 | INSERTED64(new_val, 32, 63)));
3022 cpu_set_decrementer(processor, new_val);
3033 PPC_INSN_TO_SPR(RS_BITMASK, n);
3035 0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3036 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3037 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3038 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3039 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3040 int n = (SPR{5:9} << 5) | SPR{0:4};
3041 if (SPR{0} && IS_PROBLEM_STATE(processor))
3042 program_interrupt(processor, cia,
3043 privileged_instruction_program_interrupt);
3044 else if (!spr_is_valid(n))
3045 program_interrupt(processor, cia,
3046 illegal_instruction_program_interrupt);
3048 /* HACK - some SPR's need to get their value extracted specially */
3051 PPC_INSN_FROM_SPR(RT_BITMASK, n);
3053 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3054 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3055 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3056 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3057 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3062 unsigned_word mask = 0;
3064 for (f = 0; f < 8; f++) {
3065 if (FXM & (0x80 >> f))
3066 mask |= (0xf << 4*(7-f));
3068 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3070 PPC_INSN_MTCR(RS_BITMASK, FXM);
3072 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3074 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3075 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3076 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3077 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3078 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3079 *rT = (unsigned32)CR;
3080 PPC_INSN_MFCR(RT_BITMASK);
3083 # I.4.6.2 Floating-Point Load Instructions
3086 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3087 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3088 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3089 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3090 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3096 *frT = DOUBLE(MEM(unsigned, EA, 4));
3097 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3099 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3100 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3101 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3102 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3103 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3109 *frT = DOUBLE(MEM(unsigned, EA, 4));
3110 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3112 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3113 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3114 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3115 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3116 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3119 program_interrupt(processor, cia,
3120 illegal_instruction_program_interrupt);
3122 *frT = DOUBLE(MEM(unsigned, EA, 4));
3124 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3126 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3127 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3128 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3129 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3130 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3133 program_interrupt(processor, cia,
3134 illegal_instruction_program_interrupt);
3136 *frT = DOUBLE(MEM(unsigned, EA, 4));
3138 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3140 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3141 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3142 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3143 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3144 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3150 *frT = MEM(unsigned, EA, 8);
3151 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3153 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3154 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3155 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3156 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3157 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3163 *frT = MEM(unsigned, EA, 8);
3164 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3166 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3167 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3168 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3169 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3170 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3173 program_interrupt(processor, cia,
3174 illegal_instruction_program_interrupt);
3176 *frT = MEM(unsigned, EA, 8);
3178 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3180 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3181 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3182 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3183 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3184 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3187 program_interrupt(processor, cia,
3188 illegal_instruction_program_interrupt);
3190 *frT = MEM(unsigned, EA, 8);
3192 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3196 # I.4.6.3 Floating-Point Store Instructions
3199 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3200 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3201 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3202 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3203 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3209 STORE(EA, 4, SINGLE(*frS));
3210 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3212 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3213 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3214 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3215 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3216 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3222 STORE(EA, 4, SINGLE(*frS));
3223 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3225 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3226 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3227 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3228 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3229 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3232 program_interrupt(processor, cia,
3233 illegal_instruction_program_interrupt);
3235 STORE(EA, 4, SINGLE(*frS));
3237 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3239 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3240 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3241 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3242 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3243 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3246 program_interrupt(processor, cia,
3247 illegal_instruction_program_interrupt);
3249 STORE(EA, 4, SINGLE(*frS));
3251 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3253 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3254 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3255 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3256 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3257 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3264 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3266 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3267 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3268 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3269 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3270 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3277 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3279 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3280 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3281 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3282 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3283 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3286 program_interrupt(processor, cia,
3287 illegal_instruction_program_interrupt);
3291 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3293 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3294 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3295 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3296 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3297 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3300 program_interrupt(processor, cia,
3301 illegal_instruction_program_interrupt);
3305 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3309 # I.4.6.4 Floating-Point Move Instructions
3312 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3313 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3314 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3315 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3316 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3319 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3321 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3322 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3323 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3324 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3325 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3326 *frT = *frB ^ BIT64(0);
3328 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3330 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3331 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3332 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3333 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3334 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3335 *frT = *frB & ~BIT64(0);
3337 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3339 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3340 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3341 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3342 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3343 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3344 *frT = *frB | BIT64(0);
3346 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3350 # I.4.6.5 Floating-Point Arithmetic Instructions
3353 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3354 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3355 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3356 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3357 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3359 if (is_invalid_operation(processor, cia,
3361 fpscr_vxsnan | fpscr_vxisi,
3364 invalid_arithemetic_operation(processor, cia,
3366 0, /*instruction_is_frsp*/
3367 0, /*instruction_is_convert_to_64bit*/
3368 0, /*instruction_is_convert_to_32bit*/
3369 0); /*single-precision*/
3373 double s = *(double*)frA + *(double*)frB;
3377 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3379 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3380 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3381 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3382 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3383 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3385 if (is_invalid_operation(processor, cia,
3387 fpscr_vxsnan | fpscr_vxisi,
3390 invalid_arithemetic_operation(processor, cia,
3392 0, /*instruction_is_frsp*/
3393 0, /*instruction_is_convert_to_64bit*/
3394 0, /*instruction_is_convert_to_32bit*/
3395 1); /*single-precision*/
3399 float s = *(double*)frA + *(double*)frB;
3403 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3405 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3406 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3407 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3408 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3409 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3411 if (is_invalid_operation(processor, cia,
3413 fpscr_vxsnan | fpscr_vxisi,
3416 invalid_arithemetic_operation(processor, cia,
3418 0, /*instruction_is_frsp*/
3419 0, /*instruction_is_convert_to_64bit*/
3420 0, /*instruction_is_convert_to_32bit*/
3421 0); /*single-precision*/
3425 double s = *(double*)frA - *(double*)frB;
3429 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3431 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3432 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3433 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3434 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3435 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3437 if (is_invalid_operation(processor, cia,
3439 fpscr_vxsnan | fpscr_vxisi,
3442 invalid_arithemetic_operation(processor, cia,
3444 0, /*instruction_is_frsp*/
3445 0, /*instruction_is_convert_to_64bit*/
3446 0, /*instruction_is_convert_to_32bit*/
3447 1); /*single-precision*/
3451 float s = *(double*)frA - *(double*)frB;
3455 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3457 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3458 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3459 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3460 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3461 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3463 if (is_invalid_operation(processor, cia,
3465 fpscr_vxsnan | fpscr_vximz,
3468 invalid_arithemetic_operation(processor, cia,
3470 0, /*instruction_is_frsp*/
3471 0, /*instruction_is_convert_to_64bit*/
3472 0, /*instruction_is_convert_to_32bit*/
3473 0); /*single-precision*/
3477 double s = *(double*)frA * *(double*)frC;
3481 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3483 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3484 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3485 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3486 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3487 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3489 if (is_invalid_operation(processor, cia,
3491 fpscr_vxsnan | fpscr_vximz,
3494 invalid_arithemetic_operation(processor, cia,
3496 0, /*instruction_is_frsp*/
3497 0, /*instruction_is_convert_to_64bit*/
3498 0, /*instruction_is_convert_to_32bit*/
3499 1); /*single-precision*/
3503 float s = *(double*)frA * *(double*)frC;
3507 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3509 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3510 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3511 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3512 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3513 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3515 if (is_invalid_operation(processor, cia,
3517 fpscr_vxsnan | fpscr_vxzdz,
3520 invalid_arithemetic_operation(processor, cia,
3522 0, /*instruction_is_frsp*/
3523 0, /*instruction_is_convert_to_64bit*/
3524 0, /*instruction_is_convert_to_32bit*/
3525 0); /*single-precision*/
3529 double s = *(double*)frA / *(double*)frB;
3533 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3535 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3536 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3537 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3538 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3539 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3541 if (is_invalid_operation(processor, cia,
3543 fpscr_vxsnan | fpscr_vxzdz,
3546 invalid_arithemetic_operation(processor, cia,
3548 0, /*instruction_is_frsp*/
3549 0, /*instruction_is_convert_to_64bit*/
3550 0, /*instruction_is_convert_to_32bit*/
3551 1); /*single-precision*/
3555 float s = *(double*)frA / *(double*)frB;
3559 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3561 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3562 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3563 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3564 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3565 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3567 double product; /*HACK! - incorrectly loosing precision ... */
3568 /* compute the multiply */
3569 if (is_invalid_operation(processor, cia,
3571 fpscr_vxsnan | fpscr_vximz,
3574 invalid_arithemetic_operation(processor, cia,
3575 (unsigned64*)&product, *frA, 0, *frC,
3576 0, /*instruction_is_frsp*/
3577 0, /*instruction_is_convert_to_64bit*/
3578 0, /*instruction_is_convert_to_32bit*/
3579 0); /*single-precision*/
3583 product = *(double*)frA * *(double*)frC;
3585 /* compute the add */
3586 if (is_invalid_operation(processor, cia,
3588 fpscr_vxsnan | fpscr_vxisi,
3591 invalid_arithemetic_operation(processor, cia,
3592 frT, product, *frB, 0,
3593 0, /*instruction_is_frsp*/
3594 0, /*instruction_is_convert_to_64bit*/
3595 0, /*instruction_is_convert_to_32bit*/
3596 0); /*single-precision*/
3600 double s = product + *(double*)frB;
3604 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3606 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3607 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3608 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3609 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3610 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3612 float product; /*HACK! - incorrectly loosing precision ... */
3613 /* compute the multiply */
3614 if (is_invalid_operation(processor, cia,
3616 fpscr_vxsnan | fpscr_vximz,
3619 invalid_arithemetic_operation(processor, cia,
3620 (unsigned64*)&product, *frA, 0, *frC,
3621 0, /*instruction_is_frsp*/
3622 0, /*instruction_is_convert_to_64bit*/
3623 0, /*instruction_is_convert_to_32bit*/
3624 0); /*single-precision*/
3628 product = *(double*)frA * *(double*)frC;
3630 /* compute the add */
3631 if (is_invalid_operation(processor, cia,
3633 fpscr_vxsnan | fpscr_vxisi,
3636 invalid_arithemetic_operation(processor, cia,
3637 frT, product, *frB, 0,
3638 0, /*instruction_is_frsp*/
3639 0, /*instruction_is_convert_to_64bit*/
3640 0, /*instruction_is_convert_to_32bit*/
3641 0); /*single-precision*/
3645 float s = product + *(double*)frB;
3646 *(double*)frT = (double)s;
3649 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3651 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3652 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3653 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3654 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3655 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3657 double product; /*HACK! - incorrectly loosing precision ... */
3658 /* compute the multiply */
3659 if (is_invalid_operation(processor, cia,
3661 fpscr_vxsnan | fpscr_vximz,
3664 invalid_arithemetic_operation(processor, cia,
3665 (unsigned64*)&product, *frA, 0, *frC,
3666 0, /*instruction_is_frsp*/
3667 0, /*instruction_is_convert_to_64bit*/
3668 0, /*instruction_is_convert_to_32bit*/
3669 0); /*single-precision*/
3673 product = *(double*)frA * *(double*)frC;
3675 /* compute the subtract */
3676 if (is_invalid_operation(processor, cia,
3678 fpscr_vxsnan | fpscr_vxisi,
3681 invalid_arithemetic_operation(processor, cia,
3682 frT, product, *frB, 0,
3683 0, /*instruction_is_frsp*/
3684 0, /*instruction_is_convert_to_64bit*/
3685 0, /*instruction_is_convert_to_32bit*/
3686 0); /*single-precision*/
3690 double s = product - *(double*)frB;
3694 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3696 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
3697 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3698 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3699 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3700 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3702 float product; /*HACK! - incorrectly loosing precision ... */
3703 /* compute the multiply */
3704 if (is_invalid_operation(processor, cia,
3706 fpscr_vxsnan | fpscr_vximz,
3709 invalid_arithemetic_operation(processor, cia,
3710 (unsigned64*)&product, *frA, 0, *frC,
3711 0, /*instruction_is_frsp*/
3712 0, /*instruction_is_convert_to_64bit*/
3713 0, /*instruction_is_convert_to_32bit*/
3714 0); /*single-precision*/
3718 product = *(double*)frA * *(double*)frC;
3720 /* compute the subtract */
3721 if (is_invalid_operation(processor, cia,
3723 fpscr_vxsnan | fpscr_vxisi,
3726 invalid_arithemetic_operation(processor, cia,
3727 frT, product, *frB, 0,
3728 0, /*instruction_is_frsp*/
3729 0, /*instruction_is_convert_to_64bit*/
3730 0, /*instruction_is_convert_to_32bit*/
3731 0); /*single-precision*/
3735 float s = product - *(double*)frB;
3736 *(double*)frT = (double)s;
3739 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3741 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
3742 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3743 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3744 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3745 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3747 double product; /*HACK! - incorrectly loosing precision ... */
3748 /* compute the multiply */
3749 if (is_invalid_operation(processor, cia,
3751 fpscr_vxsnan | fpscr_vximz,
3754 invalid_arithemetic_operation(processor, cia,
3755 (unsigned64*)&product, *frA, 0, *frC,
3756 0, /*instruction_is_frsp*/
3757 0, /*instruction_is_convert_to_64bit*/
3758 0, /*instruction_is_convert_to_32bit*/
3759 0); /*single-precision*/
3763 product = *(double*)frA * *(double*)frC;
3765 /* compute the add */
3766 if (is_invalid_operation(processor, cia,
3768 fpscr_vxsnan | fpscr_vxisi,
3771 invalid_arithemetic_operation(processor, cia,
3772 frT, product, *frB, 0,
3773 0, /*instruction_is_frsp*/
3774 0, /*instruction_is_convert_to_64bit*/
3775 0, /*instruction_is_convert_to_32bit*/
3776 0); /*single-precision*/
3780 double s = -(product + *(double*)frB);
3784 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3786 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
3787 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3788 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3789 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3790 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3792 float product; /*HACK! - incorrectly loosing precision ... */
3793 /* compute the multiply */
3794 if (is_invalid_operation(processor, cia,
3796 fpscr_vxsnan | fpscr_vximz,
3799 invalid_arithemetic_operation(processor, cia,
3800 (unsigned64*)&product, *frA, 0, *frC,
3801 0, /*instruction_is_frsp*/
3802 0, /*instruction_is_convert_to_64bit*/
3803 0, /*instruction_is_convert_to_32bit*/
3804 0); /*single-precision*/
3808 product = *(double*)frA * *(double*)frC;
3810 /* compute the add */
3811 if (is_invalid_operation(processor, cia,
3813 fpscr_vxsnan | fpscr_vxisi,
3816 invalid_arithemetic_operation(processor, cia,
3817 frT, product, *frB, 0,
3818 0, /*instruction_is_frsp*/
3819 0, /*instruction_is_convert_to_64bit*/
3820 0, /*instruction_is_convert_to_32bit*/
3821 0); /*single-precision*/
3825 float s = -(product + *(double*)frB);
3826 *(double*)frT = (double)s;
3829 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3831 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
3832 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3833 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3834 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3835 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3837 double product; /*HACK! - incorrectly loosing precision ... */
3838 /* compute the multiply */
3839 if (is_invalid_operation(processor, cia,
3841 fpscr_vxsnan | fpscr_vximz,
3844 invalid_arithemetic_operation(processor, cia,
3845 (unsigned64*)&product, *frA, 0, *frC,
3846 0, /*instruction_is_frsp*/
3847 0, /*instruction_is_convert_to_64bit*/
3848 0, /*instruction_is_convert_to_32bit*/
3849 0); /*single-precision*/
3853 product = *(double*)frA * *(double*)frC;
3855 /* compute the subtract */
3856 if (is_invalid_operation(processor, cia,
3858 fpscr_vxsnan | fpscr_vxisi,
3861 invalid_arithemetic_operation(processor, cia,
3862 frT, product, *frB, 0,
3863 0, /*instruction_is_frsp*/
3864 0, /*instruction_is_convert_to_64bit*/
3865 0, /*instruction_is_convert_to_32bit*/
3866 0); /*single-precision*/
3870 double s = -(product - *(double*)frB);
3874 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3876 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
3877 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3878 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3879 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3880 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3882 float product; /*HACK! - incorrectly loosing precision ... */
3883 /* compute the multiply */
3884 if (is_invalid_operation(processor, cia,
3886 fpscr_vxsnan | fpscr_vximz,
3889 invalid_arithemetic_operation(processor, cia,
3890 (unsigned64*)&product, *frA, 0, *frC,
3891 0, /*instruction_is_frsp*/
3892 0, /*instruction_is_convert_to_64bit*/
3893 0, /*instruction_is_convert_to_32bit*/
3894 0); /*single-precision*/
3898 product = *(double*)frA * *(double*)frC;
3900 /* compute the subtract */
3901 if (is_invalid_operation(processor, cia,
3903 fpscr_vxsnan | fpscr_vxisi,
3906 invalid_arithemetic_operation(processor, cia,
3907 frT, product, *frB, 0,
3908 0, /*instruction_is_frsp*/
3909 0, /*instruction_is_convert_to_64bit*/
3910 0, /*instruction_is_convert_to_32bit*/
3911 0); /*single-precision*/
3915 float s = -(product - *(double*)frB);
3916 *(double*)frT = (double)s;
3919 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3923 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
3926 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
3927 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3928 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3929 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3930 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3933 unsigned64 frac_grx;
3934 /* split off cases for what to do */
3935 if (EXTRACTED64(*frB, 1, 11) < 897
3936 && EXTRACTED64(*frB, 1, 63) > 0) {
3937 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
3938 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
3940 if (EXTRACTED64(*frB, 1, 11) > 1150
3941 && EXTRACTED64(*frB, 1, 11) < 2047) {
3942 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3943 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
3945 if (EXTRACTED64(*frB, 1, 11) > 896
3946 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
3947 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
3948 if (EXTRACTED64(*frB, 1, 11) == 2047) {
3949 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
3950 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
3951 if (EXTRACTED64(*frB, 12, 12) == 0
3952 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
3955 Disabled_Exponent_Underflow:
3956 sign = EXTRACTED64(*frB, 0, 0);
3957 if (EXTRACTED64(*frB, 1, 11) == 0) {
3959 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3961 if (EXTRACTED64(*frB, 1, 11) > 0) {
3962 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3963 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3965 /* G|R|X == zero from above */
3966 while (exp < -126) {
3968 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
3969 | MASKED64(frac_grx, 55, 55));
3971 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
3972 Round_Single(processor, sign, &exp, &frac_grx);
3973 FPSCR_SET_XX(FPSCR & fpscr_fi);
3974 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
3975 *frT = INSERTED64(sign, 0, 0);
3976 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3977 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3979 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
3980 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
3981 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3982 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3984 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
3985 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
3986 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
3988 /*Normalize_Operand:*/
3989 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3991 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3993 *frT = (INSERTED64(sign, 0, 0)
3994 | INSERTED64(exp + 1023, 1, 11)
3995 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3998 Enabled_Exponent_Underflow:
4000 sign = EXTRACTED64(*frB, 0, 0);
4001 if (EXTRACTED64(*frB, 1, 11) == 0) {
4003 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4005 if (EXTRACTED64(*frB, 1, 11) > 0) {
4006 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4007 frac_grx = (BIT64(0) |
4008 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4010 /*Normalize_Operand:*/
4011 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4013 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4015 Round_Single(processor, sign, &exp, &frac_grx);
4016 FPSCR_SET_XX(FPSCR & fpscr_fi);
4018 *frT = (INSERTED64(sign, 0, 0)
4019 | INSERTED64(exp + 1023, 1, 11)
4020 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4021 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4022 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4024 Disabled_Exponent_Overflow:
4026 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4027 if (EXTRACTED64(*frB, 0, 0) == 0) {
4028 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4029 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4031 if (EXTRACTED64(*frB, 0, 0) == 1) {
4032 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4033 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4036 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4037 if (EXTRACTED64(*frB, 0, 0) == 0) {
4038 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4039 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4041 if (EXTRACTED64(*frB, 0, 0) == 1) {
4042 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4043 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4046 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4047 if (EXTRACTED64(*frB, 0, 0) == 0) {
4048 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4049 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4051 if (EXTRACTED64(*frB, 0, 0) == 1) {
4052 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4053 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4056 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4057 if (EXTRACTED64(*frB, 0, 0) == 0) {
4058 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4059 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4061 if (EXTRACTED64(*frB, 0, 0) == 1) {
4062 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4063 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4066 /* FPSCR[FR] <- undefined */
4070 Enabled_Exponent_Overflow:
4071 sign = EXTRACTED64(*frB, 0, 0);
4072 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4073 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4074 Round_Single(processor, sign, &exp, &frac_grx);
4075 FPSCR_SET_XX(FPSCR & fpscr_fi);
4079 *frT = (INSERTED64(sign, 0, 0)
4080 | INSERTED64(exp + 1023, 1, 11)
4081 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4082 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4083 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4087 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4088 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4094 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4095 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4100 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4101 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4106 FPSCR_OR_VX(fpscr_vxsnan);
4107 if ((FPSCR & fpscr_ve) == 0) {
4108 *frT = (MASKED64(*frB, 0, 11)
4110 | MASKED64(*frB, 13, 34));
4111 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4117 sign = EXTRACTED64(*frB, 0, 0);
4118 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4119 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4120 Round_Single(processor, sign, &exp, &frac_grx);
4121 FPSCR_SET_XX(FPSCR & fpscr_fi);
4122 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4123 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4124 *frT = (INSERTED64(sign, 0, 0)
4125 | INSERTED64(exp + 1023, 1, 11)
4126 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4127 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4128 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4131 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4133 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4135 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4137 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4139 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4140 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4141 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4142 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4143 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4145 convert_to_integer(processor, cia,
4147 fpscr_rn_round_towards_zero, 32);
4149 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4151 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4152 int sign = EXTRACTED64(*frB, 0, 0);
4154 unsigned64 frac = *frB;
4155 if (frac == 0) goto Zero_Operand;
4156 if (sign == 1) frac = ~frac + 1;
4157 while (EXTRACTED64(frac, 0, 0) == 0) {
4158 /*??? do the loop 0 times if (FRB) = max negative integer */
4159 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4162 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4163 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4164 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4165 *frT = (INSERTED64(sign, 0, 0)
4166 | INSERTED64(exp + 1023, 1, 11)
4167 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4173 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4178 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4181 # I.4.6.7 Floating-Point Compare Instructions
4184 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4185 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4186 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4187 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4188 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4191 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4192 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4193 else if (is_less_than(frA, frB))
4194 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4195 else if (is_greater_than(frA, frB))
4196 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4198 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4200 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4201 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4202 FPSCR_OR_VX(fpscr_vxsnan);
4204 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4206 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4207 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4208 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4209 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4210 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4213 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4214 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4215 else if (is_less_than(frA, frB))
4216 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4217 else if (is_greater_than(frA, frB))
4218 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4220 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4222 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4223 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4224 FPSCR_OR_VX(fpscr_vxsnan);
4225 if ((FPSCR & fpscr_ve) == 0)
4226 FPSCR_OR_VX(fpscr_vxvc);
4228 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4229 FPSCR_OR_VX(fpscr_vxvc);
4232 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4236 # I.4.6.8 Floating-Point Status and Control Register Instructions
4239 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4241 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4243 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4245 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4247 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4249 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4253 # I.A.1.1 Floating-Point Store Instruction
4255 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4258 # I.A.1.2 Floating-Point Arithmetic Instructions
4261 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
4263 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4265 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
4267 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4270 # I.A.1.3 Floating-Point Select Instruction
4273 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4277 # II.3.2 Cache Management Instructions
4280 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4281 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4282 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4283 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4284 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4285 /* blindly flush all instruction cache entries */
4286 #if WITH_IDECODE_CACHE_SIZE
4287 cpu_flush_icache(processor);
4289 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4291 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4292 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4293 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4294 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4295 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4296 cpu_synchronize_context(processor);
4297 PPC_INSN_INT(0, 0, 0);
4301 # II.3.2.2 Data Cache Instructions
4304 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4305 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4306 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4307 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4308 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4309 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4310 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4312 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4313 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4314 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4315 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4316 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4317 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4318 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4320 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4321 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4322 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4323 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4324 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4325 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4326 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4328 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4329 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4330 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4331 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4332 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4333 TRACE(trace_tbd,("Data Cache Block Store\n"));
4334 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4336 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4337 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4338 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4339 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4340 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4341 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4342 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4345 # II.3.3 Enforce In-order Execution of I/O Instruction
4348 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4349 /* Since this model has no instruction overlap
4350 this instruction need do nothing */
4353 # II.4.1 Time Base Instructions
4356 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4357 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4358 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4359 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4360 int n = (tbr{5:9} << 5) | tbr{0:4};
4362 if (is_64bit_implementation) *rT = TB;
4363 else *rT = EXTRACTED64(TB, 32, 63);
4365 else if (n == 269) {
4366 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4367 else *rT = EXTRACTED64(TB, 0, 31);
4370 program_interrupt(processor, cia,
4371 illegal_instruction_program_interrupt);
4375 # III.2.3.1 System Linkage Instructions
4378 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4379 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4380 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4381 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4382 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4383 if (IS_PROBLEM_STATE(processor)) {
4384 program_interrupt(processor, cia,
4385 privileged_instruction_program_interrupt);
4388 MSR = (MASKED(SRR1, 0, 32)
4389 | MASKED(SRR1, 37, 41)
4390 | MASKED(SRR1, 48, 63));
4391 NIA = MASKED(SRR0, 0, 61);
4392 cpu_synchronize_context(processor);
4396 # III.3.4.1 Move to/from System Register Instructions
4399 #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4400 #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4401 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4402 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4403 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4404 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4405 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4406 if (IS_PROBLEM_STATE(processor))
4407 program_interrupt(processor, cia,
4408 privileged_instruction_program_interrupt);
4412 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4413 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4414 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4415 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4416 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4417 if (IS_PROBLEM_STATE(processor))
4418 program_interrupt(processor, cia,
4419 privileged_instruction_program_interrupt);
4425 # III.4.11.1 Cache Management Instructions
4428 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4429 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4430 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4431 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4432 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4433 if (IS_PROBLEM_STATE(processor))
4434 program_interrupt(processor, cia,
4435 privileged_instruction_program_interrupt);
4437 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4440 # III.4.11.2 Segment Register Manipulation Instructions
4443 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4444 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4445 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4446 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4447 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4448 if (IS_PROBLEM_STATE(processor))
4449 program_interrupt(processor, cia,
4450 privileged_instruction_program_interrupt);
4454 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4455 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4456 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4457 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4458 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4459 if (IS_PROBLEM_STATE(processor))
4460 program_interrupt(processor, cia,
4461 privileged_instruction_program_interrupt);
4463 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4465 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4466 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4467 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4468 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4469 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4470 if (IS_PROBLEM_STATE(processor))
4471 program_interrupt(processor, cia,
4472 privileged_instruction_program_interrupt);
4476 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4477 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4478 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4479 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4480 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4481 if (IS_PROBLEM_STATE(processor))
4482 program_interrupt(processor, cia,
4483 privileged_instruction_program_interrupt);
4485 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4489 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4492 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4494 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4496 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4498 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4500 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4504 # III.A.1.2 External Access Instructions
4507 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4509 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed