2 # This file is part of the program psim.
4 # Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
8 # The pseudo-code that appears below, translated into C, was copied
9 # by Andrew Cagney of Moss Vale, Australia.
11 # This pseudo-code is copied by permission from the publication
12 # "The PowerPC Architecture: A Specification for A New Family of
13 # RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by
14 # International Business Machines Corporation.
16 # THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER
17 # EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES
18 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 # This program is free software; you can redistribute it and/or modify
23 # it under the terms of the GNU General Public License as published by
24 # the Free Software Foundation; either version 2 of the License, or
25 # (at your option) any later version.
27 # This program is distributed in the hope that it will be useful,
28 # but WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 # GNU General Public License for more details.
32 # You should have received a copy of the GNU General Public License
33 # along with this program; if not, write to the Free Software
34 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 # 1 Instruction format as a `start-bit,content' pairs.
42 # the content is one of a digit, field name or `/' (aka.0)
46 # 3 Flags: 64 - 64bit only
47 # f - floating point enabled required
54 # For flags marked 'model', the fields are interpreted as follows:
62 # 4 String name for model
64 # 5 Specific CPU model, must be an identifier
66 # 6 Comma separated list of functional units
70 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
71 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
72 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
73 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
77 #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \
78 if (WITH_MODEL_ISSUE) \
79 ppc_insn_int(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK, (RC) ? (1 << 0) : 0)
81 #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \
82 if (WITH_MODEL_ISSUE) \
83 ppc_insn_int(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK)
85 #define PPC_INSN_CR(OUT_MASK, IN_MASK) \
86 if (WITH_MODEL_ISSUE) \
87 ppc_insn_cr(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK)
89 #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \
90 if (WITH_MODEL_ISSUE) \
91 ppc_insn_float(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK, (RC) ? (1 << 1) : 0)
93 #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \
94 if (WITH_MODEL_ISSUE) \
95 ppc_insn_float(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK)
97 #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \
98 if (WITH_MODEL_ISSUE) \
99 ppc_insn_int_float(my_index, processor, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK)
101 #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \
102 if (WITH_MODEL_ISSUE) \
103 ppc_insn_from_spr(my_index, processor, cpu_model(processor), INT_MASK, SPR)
105 #define PPC_INSN_TO_SPR(INT_MASK, SPR) \
106 if (WITH_MODEL_ISSUE) \
107 ppc_insn_to_spr(my_index, processor, cpu_model(processor), INT_MASK, SPR)
109 #define PPC_INSN_MFCR(INT_MASK) \
110 if (WITH_MODEL_ISSUE) \
111 ppc_insn_mfcr(my_index, processor, cpu_model(processor), INT_MASK)
114 typedef enum _ppc_function_unit {
115 PPC_UNIT_BAD, /* unknown function unit */
116 PPC_UNIT_IU, /* integer unit (601/603 style) */
117 PPC_UNIT_SRU, /* system register unit (601/603 style) */
118 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
119 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
120 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
121 PPC_UNIT_FPU, /* floating point unit */
122 PPC_UNIT_LSU, /* load/store unit */
123 PPC_UNIT_BPU, /* branch unit */
124 nr_ppc_function_units
127 /* Structure to hold timing information on a per instruction basis */
129 ppc_function_unit first_unit; /* first functional unit this insn could use */
130 ppc_function_unit second_unit; /* second functional unit this insn could use */
131 signed16 issue; /* # cycles before function unit can process other insns */
132 signed16 done; /* # cycles before insn is done */
133 unsigned32 flags; /* any flags that are needed */
136 /* Register mappings in status masks */
137 #define PPC_CR_REG 0 /* start of CR0 .. CR7 */
138 #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */
140 #define PPC_NO_SPR (-1) /* flag for no SPR register */
142 /* Structure for each functional unit that is busy */
143 typedef struct _model_busy model_busy;
145 model_busy *next; /* next function unit */
146 ppc_function_unit unit; /* function unit name */
147 unsigned32 int_busy; /* int registers that are busy */
148 unsigned32 fp_busy; /* floating point registers that are busy */
149 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
150 signed16 spr_busy; /* SPR register that is busy or PPC_NO_SPR */
151 signed8 issue; /* # of cycles until unit can accept another insn */
152 signed8 done; /* # of cycles until insn is done */
155 /* Structure to hold the current state information for the simulated CPU model */
157 cpu *processor; /* point back to processor */
158 const char *name; /* model name */
159 const model_time *timing; /* timing information */
160 model_busy *busy_list; /* list of busy function units */
161 model_busy *free_list; /* list of model_busy structs not in use */
162 count_type nr_cycles; /* # cycles */
163 count_type nr_branches; /* # branches */
164 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
165 count_type nr_branch_predict_trues; /* # branches predicted correctly */
166 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
167 count_type nr_branch_conditional[32]; /* # of each type of bc */
168 count_type nr_stalls_data; /* # of stalls for data */
169 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
170 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
171 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
172 unsigned32 int_busy; /* int registers that are busy */
173 unsigned32 fp_busy; /* floating point registers that are busy */
174 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
175 unsigned8 spr_busy[nr_of_sprs]; /* SPR registers that are busy */
176 unsigned8 busy[nr_ppc_function_units]; /* whether a function is busy or not */
179 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
180 "unknown functional unit instruction",
181 "integer functional unit instruction",
182 "system register functional unit instruction",
183 "1st single cycle integer functional unit instruction",
184 "2nd single cycle integer functional unit instruction",
185 "multiple cycle integer functional unit instruction",
186 "floating point functional unit instruction",
187 "load/store functional unit instruction",
188 "branch functional unit instruction",
191 STATIC_MODEL const char *const ppc_branch_conditional_name[32] = {
192 "branch if --CTR != 0 and condition is FALSE", /* 0000y */
193 "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
194 "branch if --CTR == 0 and condition is FALSE", /* 0001y */
195 "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
196 "branch if the condition is FALSE", /* 001zy */
197 "branch if the condition is FALSE, reverse branch likely",
198 "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */
199 "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
200 "branch if --CTR != 0 and condition is TRUE", /* 0100y */
201 "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
202 "branch if --CTR == 0 and condition is TRUE", /* 0101y */
203 "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
204 "branch if the condition is TRUE", /* 011zy */
205 "branch if the condition is TRUE, reverse branch likely",
206 "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */
207 "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
208 "branch if --CTR != 0", /* 1z00y */
209 "branch if --CTR != 0, reverse branch likely",
210 "branch if --CTR == 0", /* 1z01y */
211 "branch if --CTR == 0, reverse branch likely",
212 "branch always", /* 1z1zz */
213 "branch always (ignored bit 5 set to 1)",
214 "branch always (ignored bit 4 set to 1)", /* 1z1zz */
215 "branch always (ignored bits 4,5 set to 1)",
216 "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */
217 "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
218 "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */
219 "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
220 "branch always (ignored bit 1 set to 1)", /* 1z1zz */
221 "branch always (ignored bits 1,5 set to 1)",
222 "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */
223 "branch always (ignored bits 1,4,5 set to 1)",
227 # Trace releasing resources
228 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
230 TRACE(trace_model,("done, %s\n", ppc_function_unit_name[busy->unit]));
231 if (busy->int_busy) {
232 for(i = 0; i < 32; i++) {
233 if (((1 << i) & busy->int_busy) != 0) {
234 TRACE(trace_model, ("Register r%d is now available.\n", i));
239 for(i = 0; i < 32; i++) {
240 if (((1 << i) & busy->fp_busy) != 0) {
241 TRACE(trace_model, ("Register f%d is now available.\n", i));
245 if (busy->cr_fpscr_busy) {
246 for(i = 0; i < 8; i++) {
247 if (((1 << i) & busy->cr_fpscr_busy) != 0) {
248 TRACE(trace_model, ("Register cr%d is now available.\n", i));
251 if (busy->cr_fpscr_busy & 0x100)
252 TRACE(trace_model, ("Register fpscr is now available.\n"));
254 if (busy->spr_busy != PPC_NO_SPR)
255 TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
257 # Trace making registers busy
258 void::model-static::model_trace_make_busy:model_data *model_ptr, unsigned32 int_mask, unsigned32 fp_mask, unsigned32 cr_mask
261 for(i = 0; i < 32; i++) {
262 if (((1 << i) & int_mask) != 0) {
263 TRACE(trace_model, ("Register r%d is now busy.\n", i));
268 for(i = 0; i < 32; i++) {
269 if (((1 << i) & fp_mask) != 0) {
270 TRACE(trace_model, ("Register f%d is now busy.\n", i));
275 for(i = 0; i < 8; i++) {
276 if (((1 << i) & cr_mask) != 0) {
277 TRACE(trace_model, ("Register cr%d is now busy.\n", i));
282 # Trace waiting for registers to become available
283 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
286 int_busy &= model_ptr->int_busy;
287 for(i = 0; i < 32; i++) {
288 if (((1 << i) & int_busy) != 0) {
289 TRACE(trace_model, ("Waiting for register r%d.\n", i));
294 fp_busy &= model_ptr->fp_busy;
295 for(i = 0; i < 32; i++) {
296 if (((1 << i) & fp_busy) != 0) {
297 TRACE(trace_model, ("Waiting for register f%d.\n", i));
301 if (cr_or_fpscr_busy) {
302 cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
303 for(i = 0; i < 8; i++) {
304 if (((1 << i) & cr_or_fpscr_busy) != 0) {
305 TRACE(trace_model, ("Waiting for register cr%d.\n", i));
308 if (cr_or_fpscr_busy & 0x100)
309 TRACE(trace_model, ("Waiting for register fpscr.\n"));
311 if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
312 TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
314 # Advance state to next cycle, releasing any registers allocated
315 void::model-internal::model_new_cycle:model_data *model_ptr
316 model_busy *cur_busy = model_ptr->busy_list;
317 model_busy *free_list = model_ptr->free_list;
318 model_busy *next_busy = (model_busy *)0;
321 model_ptr->nr_cycles++;
322 for ( ; cur_busy; cur_busy = next) {
323 next = cur_busy->next;
324 if (--cur_busy->done <= 0) { /* function unit done, release registers */
325 model_ptr->int_busy &= ~cur_busy->int_busy;
326 model_ptr->fp_busy &= ~cur_busy->fp_busy;
327 model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
328 if (cur_busy->spr_busy != PPC_NO_SPR)
329 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
331 if (WITH_TRACE && ppc_trace[trace_model])
332 model_trace_release(model_ptr, cur_busy);
334 model_ptr->busy[cur_busy->unit] = 0;
335 cur_busy->next = free_list;
336 free_list = cur_busy;
338 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
339 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
340 model_ptr->busy[cur_busy->unit] = 0;
341 cur_busy->next = next_busy;
342 next_busy = cur_busy;
345 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
346 ppc_function_unit_name[cur_busy->unit],
349 cur_busy->next = next_busy;
350 next_busy = cur_busy;
354 model_ptr->busy_list = next_busy;
355 model_ptr->free_list = free_list;
357 # Mark a function unit as busy, return the busy structure
358 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
361 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
363 if (!model_ptr->free_list) {
364 busy = ZALLOC(model_busy);
367 busy = model_ptr->free_list;
368 model_ptr->free_list = busy->next;
370 busy->next = model_ptr->busy_list;
376 busy->cr_fpscr_busy = 0;
377 busy->spr_busy = PPC_NO_SPR;
378 model_ptr->busy_list = busy;
379 model_ptr->busy[unit] = 1;
380 model_ptr->nr_units[unit]++;
383 # Make a given CR register busy
384 void::model-internal::model_make_cr_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
385 TRACE(trace_model,("Marking register cr%d as busy\n", regno));
386 busy_ptr->cr_fpscr_busy |= (1 << regno);
387 model_ptr->cr_fpscr_busy |= (1 << regno);
390 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
391 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
392 ppc_function_unit first_unit = time_ptr->first_unit;
393 ppc_function_unit second_unit = time_ptr->second_unit;
394 int stall_increment = 0;
397 if (!model_ptr->busy[first_unit])
398 return model_make_busy(model_ptr, first_unit,
399 model_ptr->timing[index].issue,
400 model_ptr->timing[index].done);
402 if (!model_ptr->busy[second_unit])
403 return model_make_busy(model_ptr, second_unit,
404 model_ptr->timing[index].issue,
405 model_ptr->timing[index].done);
407 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
408 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
410 model_new_cycle(model_ptr);
413 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
414 void::model-function::model_serialize:itable_index index, model_data *model_ptr
415 while (model_ptr->busy_list) {
416 TRACE(trace_model,("waiting for pipeline to empty\n"));
417 model_ptr->nr_stalls_serialize++;
418 model_new_cycle(model_ptr);
420 (void) model_make_busy(model_ptr,
421 model_ptr->timing[index].first_unit,
422 model_ptr->timing[index].issue,
423 model_ptr->timing[index].done);
425 # Wait for a CR to become unbusy
426 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
430 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
433 cr_mask = (1 << cr_var);
434 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
435 TRACE(trace_model,("waiting for CR %d\n", cr_var));
436 model_ptr->nr_stalls_data++;
437 model_new_cycle(model_ptr);
440 # Schedule an instruction that takes integer input registers and produces output registers & possibly sets some CR registers
441 void::model-function::ppc_insn_int:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask
442 const unsigned32 int_mask = out_mask | in_mask;
443 model_busy *busy_ptr;
446 if ((model_ptr->int_busy & int_mask) != 0) {
447 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
449 while ((model_ptr->int_busy & int_mask) != 0) {
450 if (WITH_TRACE && ppc_trace[trace_model])
451 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
453 model_ptr->nr_stalls_data++;
454 model_new_cycle(model_ptr);
458 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
459 model_ptr->int_busy |= out_mask;
460 busy_ptr->int_busy |= out_mask;
461 if (WITH_TRACE && ppc_trace[trace_model])
462 model_trace_make_busy(model_ptr, out_mask, 0, 0);
467 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
468 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
470 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
471 if (WITH_TRACE && ppc_trace[trace_model])
472 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
474 model_ptr->nr_stalls_data++;
475 model_new_cycle(model_ptr);
479 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
480 model_ptr->int_busy |= out_mask;
481 busy_ptr->int_busy |= out_mask;
482 model_ptr->cr_fpscr_busy |= cr_mask;
483 busy_ptr->cr_fpscr_busy |= cr_mask;
484 if (WITH_TRACE && ppc_trace[trace_model])
485 model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
490 # Schedule an instruction that takes floating point input registers and produces output fp registers & possibly sets some CR regs
491 void::model-function::ppc_insn_float:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask
492 const unsigned32 fp_mask = out_mask | in_mask;
493 model_busy *busy_ptr;
496 if ((model_ptr->fp_busy & fp_mask) != 0) {
497 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
499 while ((model_ptr->fp_busy & fp_mask) != 0) {
500 if (WITH_TRACE && ppc_trace[trace_model])
501 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
503 model_ptr->nr_stalls_data++;
504 model_new_cycle(model_ptr);
508 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
509 model_ptr->fp_busy |= out_mask;
510 busy_ptr->fp_busy |= out_mask;
511 if (WITH_TRACE && ppc_trace[trace_model])
512 model_trace_make_busy(model_ptr, 0, out_mask, 0);
517 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
518 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
520 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
521 if (WITH_TRACE && ppc_trace[trace_model])
522 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
524 model_ptr->nr_stalls_data++;
525 model_new_cycle(model_ptr);
529 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
530 model_ptr->fp_busy |= out_mask;
531 busy_ptr->fp_busy |= out_mask;
532 model_ptr->cr_fpscr_busy |= cr_mask;
533 busy_ptr->cr_fpscr_busy |= cr_mask;
534 if (WITH_TRACE && ppc_trace[trace_model])
535 model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
540 # Schedule an instruction that takes both int/float input registers and produces output int/float registers
541 void::model-function::ppc_insn_int_float:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 out_int_mask, const unsigned32 out_fp_mask, const unsigned32 in_int_mask, const unsigned32 in_fp_mask
542 const unsigned32 int_mask = out_int_mask | in_int_mask;
543 const unsigned32 fp_mask = out_fp_mask | in_fp_mask;
544 model_busy *busy_ptr;
546 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
547 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
549 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
550 if (WITH_TRACE && ppc_trace[trace_model])
551 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
553 model_ptr->nr_stalls_data++;
554 model_new_cycle(model_ptr);
557 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
558 model_ptr->int_busy |= out_int_mask;
559 busy_ptr->int_busy |= out_int_mask;
560 model_ptr->fp_busy |= out_fp_mask;
561 busy_ptr->fp_busy |= out_fp_mask;
562 if (WITH_TRACE && ppc_trace[trace_model])
563 model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0);
567 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
568 void::model-function::ppc_insn_from_spr:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
569 model_busy *busy_ptr;
571 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
572 if (WITH_TRACE && ppc_trace[trace_model])
573 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
575 model_ptr->nr_stalls_data++;
576 model_new_cycle(model_ptr);
579 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
580 model_ptr->int_busy |= int_mask;
581 busy_ptr->int_busy |= int_mask;
582 if (WITH_TRACE && ppc_trace[trace_model])
583 model_trace_make_busy(model_ptr, int_mask, 0, 0);
585 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
586 void::model-function::ppc_insn_to_spr:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
587 model_busy *busy_ptr;
589 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
590 if (WITH_TRACE && ppc_trace[trace_model])
591 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
593 model_ptr->nr_stalls_data++;
594 model_new_cycle(model_ptr);
597 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
598 busy_ptr->spr_busy = nSPR;
599 model_ptr->spr_busy[nSPR] = 1;
600 TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));
602 # Schedule a MFCR instruction that moves the CR into an integer regsiter
603 void::model-function::ppc_insn_mfcr:itable_index index, cpu *processor, model_data *model_ptr, unsigned32 int_mask
604 const unsigned32 cr_mask = 0xff;
605 model_busy *busy_ptr;
607 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
608 if (WITH_TRACE && ppc_trace[trace_model])
609 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
611 model_ptr->nr_stalls_data++;
612 model_new_cycle(model_ptr);
615 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
616 model_ptr->int_busy |= int_mask;
617 busy_ptr->int_busy |= int_mask;
618 if (WITH_TRACE && ppc_trace[trace_model])
619 model_trace_make_busy(model_ptr, int_mask, 0, 0);
621 # Schedule a MTCR instruction that moves an integer register into the CR
622 void::model-function::ppc_insn_mtcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rT, unsigned FXM
623 if (!WITH_MODEL_ISSUE)
627 registers *cpu_regs = cpu_registers(processor);
628 const unsigned ppc_RT = (rT - &cpu_regs->gpr[0]);
629 const unsigned32 int_mask = (1 << ppc_RT);
630 const unsigned32 cr_mask = 0xff;
631 const model_time *normal_time = &model_ptr->timing[index];
632 static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 };
633 model_busy *busy_ptr;
635 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
636 if (WITH_TRACE && ppc_trace[trace_model])
637 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
639 model_ptr->nr_stalls_data++;
640 model_new_cycle(model_ptr);
643 /* If only one bit is being moved, use the SCIU, not the MCIU on the 604 */
644 if (CURRENT_MODEL == MODEL_ppc604 && (FXM & (FXM-1)) == 0) {
645 normal_time = &ppc604_1bit_time;
648 busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
649 busy_ptr->cr_fpscr_busy |= cr_mask;
650 model_ptr->cr_fpscr_busy |= cr_mask;
651 if (WITH_TRACE && ppc_trace[trace_model])
652 model_trace_make_busy(model_ptr, 0, 0, cr_mask);
655 # Convert a BIT32(x) number back into the original number
656 int::model-internal::ppc_undo_bit32:unsigned bitmask
657 unsigned u = 0x80000000;
659 while (u && (u & bitmask) == 0) {
666 # Schedule an instruction that takes 2 CR input registers and produces an output CR register
667 void::model-function::ppc_insn_cr2:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned crA_bit, unsigned crB_bit
668 if (!WITH_MODEL_ISSUE)
672 const unsigned ppc_CRA = ppc_undo_bit32(crA_bit);
673 const unsigned ppc_CRB = ppc_undo_bit32(crB_bit);
674 const unsigned32 cr_mask = (1 << ppc_CRA) | (1 << ppc_CRB) | (1 << crD);
675 model_busy *busy_ptr;
677 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
678 if (WITH_TRACE && ppc_trace[trace_model])
679 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
681 model_ptr->nr_stalls_data++;
682 model_new_cycle(model_ptr);
685 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
686 model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
689 # Schedule an instruction that takes 1 CR input registers and produces an output CR register
690 void::model-function::ppc_insn_cr1:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned CRA
691 if (!WITH_MODEL_ISSUE)
695 const unsigned32 cr_mask = (1 << CRA) | (1 << crD);
696 model_busy *busy_ptr;
698 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
699 if (WITH_TRACE && ppc_trace[trace_model])
700 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
702 model_ptr->nr_stalls_data++;
703 model_new_cycle(model_ptr);
706 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
707 model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
710 model_data *::model-function::model_create:cpu *processor
711 model_data *model_ptr = ZALLOC(model_data);
712 ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
713 model_ptr->name = model_name[CURRENT_MODEL];
714 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
715 model_ptr->processor = processor;
716 model_ptr->nr_cycles = 1;
719 void::model-function::model_init:model_data *model_ptr
721 void::model-function::model_halt:model_data *model_ptr
722 /* Let pipeline drain */
723 while (model_ptr->busy_list)
724 model_new_cycle(model_ptr);
726 model_print *::model-function::model_mon_info:model_data *model_ptr
733 head = tail = ZALLOC(model_print);
734 tail->count = model_ptr->nr_cycles;
735 tail->name = "cycle";
736 tail->suffix_plural = "s";
737 tail->suffix_singular = "";
739 if (model_ptr->nr_stalls_data) {
740 tail->next = ZALLOC(model_print);
742 tail->count = model_ptr->nr_stalls_data;
743 tail->name = "stall";
744 tail->suffix_plural = "s waiting for data";
745 tail->suffix_singular = " waiting for data";
748 if (model_ptr->nr_stalls_unit) {
749 tail->next = ZALLOC(model_print);
751 tail->count = model_ptr->nr_stalls_unit;
752 tail->name = "stall";
753 tail->suffix_plural = "s waiting for a function unit";
754 tail->suffix_singular = " waiting for a function unit";
757 if (model_ptr->nr_stalls_serialize) {
758 tail->next = ZALLOC(model_print);
760 tail->count = model_ptr->nr_stalls_serialize;
761 tail->name = "stall";
762 tail->suffix_plural = "s waiting for serialization";
763 tail->suffix_singular = " waiting for serialization";
766 if (model_ptr->nr_branches) {
767 tail->next = ZALLOC(model_print);
769 tail->count = model_ptr->nr_branches;
770 tail->name = "branch";
771 tail->suffix_plural = "es";
772 tail->suffix_singular = "";
775 if (model_ptr->nr_branches_fallthrough) {
776 tail->next = ZALLOC(model_print);
778 tail->count = model_ptr->nr_branches_fallthrough;
779 tail->name = "conditional branch";
780 tail->suffix_plural = "es fell through";
781 tail->suffix_singular = " fell through";
784 if (model_ptr->nr_branch_predict_trues) {
785 tail->next = ZALLOC(model_print);
787 tail->count = model_ptr->nr_branch_predict_trues;
788 tail->name = "successful branch prediction";
789 tail->suffix_plural = "s";
790 tail->suffix_singular = "";
793 if (model_ptr->nr_branch_predict_falses) {
794 tail->next = ZALLOC(model_print);
796 tail->count = model_ptr->nr_branch_predict_falses;
797 tail->name = "unsuccessful branch prediction";
798 tail->suffix_plural = "s";
799 tail->suffix_singular = "";
802 for (j = 0; j < (sizeof(ppc_branch_conditional_name) / sizeof(ppc_branch_conditional_name[0])) ; j++) {
803 if (model_ptr->nr_branch_conditional[j]) {
804 tail->next = ZALLOC(model_print);
806 tail->count = model_ptr->nr_branch_conditional[j];
807 tail->name = ppc_branch_conditional_name[j];
808 tail->suffix_plural = " conditional branches";
809 tail->suffix_singular = " conditional branch";
814 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
815 if (model_ptr->nr_units[i]) {
816 nr_insns += model_ptr->nr_units[i];
817 tail->next = ZALLOC(model_print);
819 tail->count = model_ptr->nr_units[i];
820 tail->name = ppc_function_unit_name[i];
821 tail->suffix_plural = "s";
822 tail->suffix_singular = "";
826 tail->next = ZALLOC(model_print);
828 tail->count = nr_insns;
829 tail->name = "instruction";
830 tail->suffix_plural = "s that were accounted for in timing info";
831 tail->suffix_singular = " that was accounted for in timing info";
833 tail->next = (model_print *)0;
836 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
838 model_print *next = ptr->next;
843 void::model-function::model_branches:model_data *model_ptr, int failed, int conditional
844 model_ptr->nr_units[PPC_UNIT_BPU]++;
846 model_ptr->nr_branches_fallthrough++;
848 model_ptr->nr_branches++;
849 if (conditional >= 0)
850 model_ptr->nr_branch_conditional[conditional]++;
851 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
853 void::model-function::model_branch_predict:model_data *model_ptr, int success
855 model_ptr->nr_branch_predict_trues++;
857 model_ptr->nr_branch_predict_falses++;
860 # The following (illegal) instruction is `known' by gen and is
861 # called when ever an illegal instruction is encountered
863 program_interrupt(processor, cia,
864 illegal_instruction_program_interrupt);
868 # The following (floating point unavailable) instruction is `known' by gen
869 # and is called when ever an a floating point instruction is to be
870 # executed but floating point is make unavailable by the MSR
871 ::internal::floating_point_unavailable
872 floating_point_unavailable_interrupt(processor, cia);
877 # Floating point support functions
880 # Convert 32bit single to 64bit double
881 unsigned64::function::DOUBLE:unsigned32 WORD
883 if (EXTRACTED32(WORD, 1, 8) > 0
884 && EXTRACTED32(WORD, 1, 8) < 255) {
885 /* normalized operand */
886 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
887 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
888 | INSERTED64(not_word_1_1, 2, 2)
889 | INSERTED64(not_word_1_1, 3, 3)
890 | INSERTED64(not_word_1_1, 4, 4)
891 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
893 else if (EXTRACTED32(WORD, 1, 8) == 0
894 && EXTRACTED32(WORD, 9, 31) != 0) {
895 /* denormalized operand */
896 int sign = EXTRACTED32(WORD, 0, 0);
898 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
899 /* normalize the operand */
900 while (MASKED64(frac, 0, 0) == 0) {
904 FRT = (INSERTED64(sign, 0, 0)
905 | INSERTED64(exp + 1023, 1, 11)
906 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
908 else if (EXTRACTED32(WORD, 1, 8) == 255
909 || EXTRACTED32(WORD, 1, 31) == 0) {
910 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
911 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
912 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
913 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
914 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
917 error("DOUBLE - unknown case\n");
922 # Convert 64bit single to 32bit double
923 unsigned32::function::SINGLE:unsigned64 FRS
925 if (EXTRACTED64(FRS, 1, 11) > 896
926 || EXTRACTED64(FRS, 1, 63) == 0) {
927 /* no denormalization required (includes Zero/Infinity/NaN) */
928 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
929 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
931 else if (874 <= EXTRACTED64(FRS, 1, 11)
932 && EXTRACTED64(FRS, 1, 11) <= 896) {
933 /* denormalization required */
934 int sign = EXTRACTED64(FRS, 0, 0);
935 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
936 unsigned64 frac = (BIT64(0)
937 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
938 /* denormalize the operand */
940 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
943 WORD = (INSERTED32(sign, 0, 0)
944 | INSERTED32(0x00, 1, 8)
945 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
948 WORD = 0x0; /* ??? */
953 # round 64bit double to 64bit but single
954 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
955 /* comparisons ignore u bits */
958 int lsb = EXTRACTED64(*frac_grx, 23, 23);
959 int gbit = EXTRACTED64(*frac_grx, 24, 24);
960 int rbit = EXTRACTED64(*frac_grx, 25, 25);
961 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
962 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
963 if (lsb == 1 && gbit == 1) inc = 1;
964 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
965 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
967 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
968 if (sign == 0 && gbit == 1) inc = 1;
969 if (sign == 0 && rbit == 1) inc = 1;
970 if (sign == 0 && xbit == 1) inc = 1;
972 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
973 if (sign == 1 && gbit == 1) inc = 1;
974 if (sign == 1 && rbit == 1) inc = 1;
975 if (sign == 1 && xbit == 1) inc = 1;
977 /* work out addition in low 25 bits of out */
978 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
979 *frac_grx = INSERTED64(out, 0, 23);
980 if (out & BIT64(64 - 23 - 1 - 1)) {
981 *frac_grx = (BIT64(0) |
982 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
985 /* frac_grx[24:52] = 0 already */
987 FPSCR_SET_FI(gbit || rbit || xbit);
991 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
993 if (round_mode == fpscr_rn_round_to_nearest) {
994 if (*frac64 == 1 && gbit == 1) inc = 1;
995 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
996 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
998 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
999 if (sign == 0 && gbit == 1) inc = 1;
1000 if (sign == 0 && rbit == 1) inc = 1;
1001 if (sign == 0 && xbit == 1) inc = 1;
1003 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1004 if (sign == 1 && gbit == 1) inc = 1;
1005 if (sign == 1 && rbit == 1) inc = 1;
1006 if (sign == 1 && xbit == 1) inc = 1;
1008 /* frac[0:64] = frac[0:64} + inc */
1009 *frac += (*frac64 && inc ? 1 : 0);
1010 *frac64 = (*frac64 + inc) & 0x1;
1012 FPSCR_SET_FI(gbit | rbit | xbit);
1015 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
1018 int lsb = EXTRACTED64(*frac, 52, 52);
1019 int gbit = EXTRACTED64(*frac, 53, 53);
1020 int rbit = EXTRACTED64(*frac, 54, 54);
1021 int xbit = EXTRACTED64(*frac, 55, 55);
1022 if (round_mode == fpscr_rn_round_to_nearest) {
1023 if (lsb == 1 && gbit == 1) inc = 1;
1024 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1025 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1027 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1028 if (sign == 0 && gbit == 1) inc = 1;
1029 if (sign == 0 && rbit == 1) inc = 1;
1030 if (sign == 0 && xbit == 1) inc = 1;
1032 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1033 if (sign == 1 && gbit == 1) inc = 1;
1034 if (sign == 1 && rbit == 1) inc = 1;
1035 if (sign == 1 && xbit == 1) inc = 1;
1037 /* frac//carry_out = frac + inc */
1038 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1039 carry_out = EXTRACTED64(*frac, 0, 0);
1041 if (carry_out == 1) *exp = *exp + 1;
1043 FPSCR_SET_FI(gbit | rbit | xbit);
1044 FPSCR_SET_XX(FPSCR & fpscr_fi);
1047 # conversion of FP to integer
1048 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
1051 unsigned64 frac = 0;
1056 int sign = EXTRACTED64(frb, 0, 0);
1057 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1058 goto Infinity_Operand;
1059 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1061 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1063 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
1064 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1065 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1066 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1067 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1070 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1071 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1074 gbit = 0, rbit = 0, xbit = 0;
1075 for (i = 1; i <= 63 - exp; i++) {
1079 frac64 = EXTRACTED64(frac, 63, 63);
1080 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1082 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1083 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1086 frac += (frac64 ? 1 : 0);
1087 frac64 = (frac64 + 1) & 0x1;
1089 if (tgt_precision == 32 /* can ignore frac64 in compare */
1090 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1092 if (tgt_precision == 64 /* can ignore frac64 in compare */
1093 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1095 if (tgt_precision == 32 /* can ignore frac64 in compare */
1096 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1098 if (tgt_precision == 64 /* can ignore frac64 in compare */
1099 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1101 FPSCR_SET_XX(FPSCR & fpscr_fi);
1102 if (tgt_precision == 32)
1103 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1104 if (tgt_precision == 64)
1105 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1106 /*FPSCR[fprf] = undefined */
1112 FPSCR_OR_VX(fpscr_vxcvi);
1113 if ((FPSCR & fpscr_ve) == 0) {
1114 if (tgt_precision == 32) {
1115 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1116 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1119 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1120 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1122 /* FPSCR[FPRF] = undefined */
1129 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1130 if ((FPSCR & fpscr_ve) == 0) {
1131 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1132 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1133 /* FPSCR[fprf] = undefined */
1140 FPSCR_OR_VX(fpscr_vxcvi);
1141 if ((FPSCR & fpscr_ve) == 0) {
1142 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1143 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1144 /* FPSCR[fprf] = undefined */
1151 FPSCR_OR_VX(fpscr_vxcvi);
1152 if ((FPSCR & fpscr_ve) == 0) {
1153 if (tgt_precision == 32) {
1154 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1155 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1158 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1159 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1161 /* FPSCR[fprf] = undefined */
1167 # extract out raw fields of a FP number
1168 int::function::sign:unsigned64 FRS
1169 return (MASKED64(FRS, 0, 0)
1172 int::function::biased_exp:unsigned64 frs, int single
1174 return EXTRACTED64(frs, 1, 8);
1176 return EXTRACTED64(frs, 1, 11);
1177 unsigned64::function::fraction:unsigned64 frs, int single
1179 return EXTRACTED64(frs, 9, 31);
1181 return EXTRACTED64(frs, 12, 63);
1183 # a number?, each of the below return +1 or -1 (based on sign bit)
1185 int::function::is_nor:unsigned64 frs, int single
1186 int exp = biased_exp(frs, single);
1188 && exp <= (single ? 254 : 2046));
1189 int::function::is_zero:unsigned64 FRS
1190 return (MASKED64(FRS, 1, 63) == 0
1193 int::function::is_den:unsigned64 frs, int single
1194 int exp = biased_exp(frs, single);
1195 unsigned64 frac = fraction(frs, single);
1196 return (exp == 0 && frac != 0
1199 int::function::is_inf:unsigned64 frs, int single
1200 int exp = biased_exp(frs, single);
1201 int frac = fraction(frs, single);
1202 return (exp == (single ? 255 : 2047) && frac == 0
1205 int::function::is_NaN:unsigned64 frs, int single
1206 int exp = biased_exp(frs, single);
1207 int frac = fraction(frs, single);
1208 return (exp == (single ? 255 : 2047) && frac != 0
1211 int::function::is_SNaN:unsigned64 frs, int single
1212 return (is_NaN(frs, single)
1213 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1216 int::function::is_QNaN:unsigned64 frs, int single
1217 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1218 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1219 return *(double*)fra < *(double*)frb;
1220 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1221 return *(double*)fra > *(double*)frb;
1222 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1223 return *(double*)fra == *(double*)frb;
1226 # which quiet nan should become the result
1227 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1229 if (is_NaN(fra, single))
1231 else if (is_NaN(frb, single))
1232 if (instruction_is_frsp)
1233 frt = MASKED64(frb, 0, 34);
1236 else if (is_NaN(frc, single))
1238 else if (generate_qnan)
1239 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1241 error("select_qnan - default reached\n");
1245 # detect invalid operation
1246 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1248 if ((check & fpscr_vxsnan)
1249 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1250 FPSCR_OR_VX(fpscr_vxsnan);
1253 if ((check & fpscr_vxisi)
1254 && (is_inf(fra, single) && is_inf(frb, single))
1255 && ((negate && sign(fra) != sign(frb))
1256 || (!negate && sign(fra) == sign(frb)))) {
1257 /*FIXME: don't handle inf-inf VS inf+-inf */
1258 FPSCR_OR_VX(fpscr_vxisi);
1261 if ((check & fpscr_vxidi)
1262 && (is_inf(fra, single) && is_inf(frb, single))) {
1263 FPSCR_OR_VX(fpscr_vxidi);
1266 if ((check & fpscr_vxzdz)
1267 && (is_zero(fra) && is_zero(frb))) {
1268 FPSCR_OR_VX(fpscr_vxzdz);
1271 if ((check & fpscr_vximz)
1272 && (is_zero(fra) && is_inf(frb, single))) {
1273 FPSCR_OR_VX(fpscr_vximz);
1276 if ((check & fpscr_vxvc)
1277 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1278 FPSCR_OR_VX(fpscr_vxvc);
1281 if ((check & fpscr_vxsoft)) {
1282 FPSCR_OR_VX(fpscr_vxsoft);
1285 if ((check & fpscr_vxsqrt)
1287 FPSCR_OR_VX(fpscr_vxsqrt);
1290 /* if ((check && fpscr_vxcvi) {
1291 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1292 FPSCR_OR_VX(fpscr_vxcvi);
1302 # handle case of invalid operation
1303 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
1304 if (FPSCR & fpscr_ve) {
1305 /* invalid operation exception enabled */
1309 /* fpscr_FPRF unchanged */
1312 /* invalid operation exception disabled */
1313 if (instruction_is_convert_to_64bit) {
1316 else if (instruction_is_convert_to_32bit) {
1319 else { /* arrith, frsp */
1320 *frt = select_qnan(fra, frb, frc,
1321 instruction_is_frsp, 0/*generate*/, single);
1324 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1332 # I.2.4.1 Branch Instructions
1334 0.18,6.LI,30.AA,31.LK:I:t::Branch
1335 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1336 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1337 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1338 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1339 if (AA) NIA = IEA(EXTS(LI_0b00));
1340 else NIA = IEA(CIA + EXTS(LI_0b00));
1341 if (LK) LR = (spreg)CIA+4;
1342 model_branches(cpu_model(processor), 1, -1);
1344 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
1345 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1346 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1347 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1348 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1349 int M, ctr_ok, cond_ok, succeed;
1351 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1352 if (is_64bit_implementation && is_64bit_mode) M = 0;
1354 if (!BO{2}) CTR = CTR - 1;
1355 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1356 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1357 if (ctr_ok && cond_ok) {
1358 if (AA) NIA = IEA(EXTS(BD_0b00));
1359 else NIA = IEA(CIA + EXTS(BD_0b00));
1364 if (LK) LR = (spreg)IEA(CIA + 4);
1365 model_branches(cpu_model(processor), succeed, BO);
1368 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1369 reverse = EXTS(BD_0b00) < 0;
1370 } else { /* branch prediction bit not set */
1371 reverse = EXTS(BD_0b00) >= 0;
1373 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1376 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
1377 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1378 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1379 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1380 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1381 int M, ctr_ok, cond_ok, succeed;
1382 if (is_64bit_implementation && is_64bit_mode) M = 0;
1385 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1386 if (!BO{2}) CTR = CTR - 1;
1387 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1388 cond_ok = BO{0} || (CR{BI} == BO{1});
1389 if (ctr_ok && cond_ok) {
1395 if (LK) LR = (spreg)IEA(CIA + 4);
1396 model_branches(cpu_model(processor), succeed, BO);
1398 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1400 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
1401 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1402 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1403 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1404 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1405 int cond_ok, succeed;
1407 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1408 cond_ok = BO{0} || (CR{BI} == BO{1});
1410 NIA = IEA(CTR_0b00);
1415 if (LK) LR = (spreg)IEA(CIA + 4);
1416 model_branches(cpu_model(processor), succeed, BO);
1418 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1421 # I.2.4.2 System Call Instruction
1423 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
1424 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1425 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1426 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1427 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1428 model_serialize(my_index, cpu_model(processor));
1429 system_call_interrupt(processor, cia);
1432 # I.2.4.3 Condition Register Logical Instructions
1434 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1435 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1436 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1437 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1438 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1439 BLIT32(CR, BT, CR{BA} && CR{BB});
1440 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1442 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1443 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1444 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1445 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1446 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1447 BLIT32(CR, BT, CR{BA} || CR{BB});
1448 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1450 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1451 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1452 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1453 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1454 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1455 BLIT32(CR, BT, CR{BA} != CR{BB});
1456 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1458 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1459 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1460 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1461 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1462 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1463 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1464 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1466 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1467 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1468 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1469 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1470 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1471 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1472 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1474 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1475 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1476 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1477 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1478 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1479 BLIT32(CR, BT, CR{BA} == CR{BB});
1480 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1482 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1483 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1484 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1485 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1486 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1487 BLIT32(CR, BT, CR{BA} && !CR{BB});
1488 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1490 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1491 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1492 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1493 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1494 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1495 BLIT32(CR, BT, CR{BA} || !CR{BB});
1496 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1499 # I.2.4.4 Condition Register Field Instruction
1501 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1502 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1503 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1504 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1505 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1506 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1507 ppc_insn_cr1(my_index, processor, cpu_model(processor), BF, BFA);
1511 # I.3.3.2 Fixed-Point Load Instructions
1514 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1515 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1516 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1517 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1518 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1524 *rT = MEM(unsigned, EA, 1);
1525 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1528 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1529 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1530 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1531 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1532 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1538 *rT = MEM(unsigned, EA, 1);
1539 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1541 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1542 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1543 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1544 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1545 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1547 if (RA == 0 || RA == RT)
1548 program_interrupt(processor, cia,
1549 illegal_instruction_program_interrupt);
1551 *rT = MEM(unsigned, EA, 1);
1553 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1555 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1556 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1557 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1558 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1559 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1561 if (RA == 0 || RA == RT)
1562 program_interrupt(processor, cia,
1563 illegal_instruction_program_interrupt);
1565 *rT = MEM(unsigned, EA, 1);
1567 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1569 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1570 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1571 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1572 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1573 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1579 *rT = MEM(unsigned, EA, 2);
1580 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1582 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1583 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1584 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1585 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1586 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1592 *rT = MEM(unsigned, EA, 2);
1593 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1595 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
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
1601 if (RA == 0 || RA == RT)
1602 program_interrupt(processor, cia,
1603 illegal_instruction_program_interrupt);
1605 *rT = MEM(unsigned, EA, 2);
1607 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1609 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1610 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1611 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1612 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1613 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1615 if (RA == 0 || RA == RT)
1616 program_interrupt(processor, cia,
1617 illegal_instruction_program_interrupt);
1619 *rT = MEM(unsigned, EA, 2);
1621 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1623 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1624 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1625 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1626 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1627 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1633 *rT = MEM(signed, EA, 2);
1634 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1636 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1637 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1638 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1639 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1640 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1646 *rT = MEM(signed, EA, 2);
1647 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1649 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
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
1655 if (RA == 0 || RA == RT)
1656 program_interrupt(processor, cia,
1657 illegal_instruction_program_interrupt);
1659 *rT = MEM(signed, EA, 2);
1660 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1662 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update 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
1668 if (RA == 0 || RA == RT)
1669 program_interrupt(processor, cia,
1670 illegal_instruction_program_interrupt);
1672 *rT = MEM(signed, EA, 2);
1674 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1676 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1677 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1678 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1679 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1680 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1686 *rT = MEM(unsigned, EA, 4);
1687 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1689 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1690 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1691 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1692 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1693 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1699 *rT = MEM(unsigned, EA, 4);
1700 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1702 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
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
1708 if (RA == 0 || RA == RT)
1709 program_interrupt(processor, cia,
1710 illegal_instruction_program_interrupt);
1712 *rT = MEM(unsigned, EA, 4);
1714 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1716 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1717 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1718 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1719 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1720 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1722 if (RA == 0 || RA == RT)
1723 program_interrupt(processor, cia,
1724 illegal_instruction_program_interrupt);
1726 *rT = MEM(unsigned, EA, 4);
1728 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1730 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1733 # if (RA == 0) b = 0;
1735 # EA = b + EXTS(DS_0b00);
1736 # *rT = MEM(signed, EA, 4);
1738 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1741 # if (RA == 0) b = 0;
1744 # *rT = MEM(signed, EA, 4);
1746 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1748 # if (RA == 0 || RA == RT)
1749 # program_interrupt(processor, cia
1750 # illegal_instruction_program_interrupt);
1752 # *rT = MEM(signed, EA, 4);
1755 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1758 # if (RA == 0) b = 0;
1760 # EA = b + EXTS(DS_0b00);
1761 # *rT = MEM(unsigned, EA, 8);
1763 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1766 # if (RA == 0) b = 0;
1769 # *rT = MEM(unsigned, EA, 8);
1771 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1773 # if (RA == 0 || RA == RT)
1774 # program_interrupt(processor, cia
1775 # illegal_instruction_program_interrupt);
1776 # EA = *rA + EXTS(DS_0b00);
1777 # *rT = MEM(unsigned, EA, 8);
1780 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1782 # if (RA == 0 || RA == RT)
1783 # program_interrupt(processor, cia
1784 # illegal_instruction_program_interrupt);
1786 # *rT = MEM(unsigned, EA, 8);
1792 # I.3.3.3 Fixed-Point Store Instructions
1795 0.38,6.RS,11.RA,16.D:D:::Store Byte
1796 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1797 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1798 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1799 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1806 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1808 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1809 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1810 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1811 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1812 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1819 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1821 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
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
1828 program_interrupt(processor, cia,
1829 illegal_instruction_program_interrupt);
1833 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1835 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1836 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1837 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1838 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1839 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1842 program_interrupt(processor, cia,
1843 illegal_instruction_program_interrupt);
1847 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1849 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1850 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1851 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1852 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1853 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1860 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1862 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1863 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1864 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1865 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1866 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1873 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1875 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
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
1882 program_interrupt(processor, cia,
1883 illegal_instruction_program_interrupt);
1887 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1889 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1890 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1891 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1892 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1893 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1896 program_interrupt(processor, cia,
1897 illegal_instruction_program_interrupt);
1901 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1903 0.36,6.RS,11.RA,16.D:D:::Store Word
1904 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1905 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1906 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1907 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1914 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1916 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
1917 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1918 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1919 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1920 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1927 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1929 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
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
1936 program_interrupt(processor, cia,
1937 illegal_instruction_program_interrupt);
1941 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1943 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
1944 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1945 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1946 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1947 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1950 program_interrupt(processor, cia,
1951 illegal_instruction_program_interrupt);
1955 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1957 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
1960 # if (RA == 0) b = 0;
1962 # EA = b + EXTS(DS_0b00);
1963 # STORE(EA, 8, *rS);
1964 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
1967 # if (RA == 0) b = 0;
1970 # STORE(EA, 8, *rS);
1971 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
1974 # program_interrupt(processor, cia
1975 # illegal_instruction_program_interrupt);
1976 # EA = *rA + EXTS(DS_0b00);
1977 # STORE(EA, 8, *rS);
1979 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
1982 # program_interrupt(processor, cia
1983 # illegal_instruction_program_interrupt);
1985 # STORE(EA, 8, *rS);
1990 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
1993 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
1994 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1995 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1996 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1997 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2003 *rT = SWAP_2(MEM(unsigned, EA, 2));
2004 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2006 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2007 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2008 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2009 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2010 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2016 *rT = SWAP_4(MEM(unsigned, EA, 4));
2017 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2019 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed 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 STORE(EA, 2, SWAP_2(*rS));
2030 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2032 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed 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 STORE(EA, 4, SWAP_4(*rS));
2043 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2047 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2050 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
2052 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2056 # I.3.3.6 Fixed-Point Move Assist Instructions
2059 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
2061 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2063 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
2065 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2069 # I.3.3.7 Storage Synchronization Instructions
2071 # HACK: Rather than monitor addresses looking for a reason
2072 # to cancel a reservation. This code instead keeps
2073 # a copy of the data read from memory. Before performing
2074 # a store, the memory area is checked to see if it has
2076 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2077 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2078 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2079 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2080 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2087 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2088 RESERVE_DATA = MEM(unsigned, EA, 4);
2090 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2092 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2099 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2100 RESERVE_DATA = MEM(unsigned, EA, 8);
2102 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2104 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2105 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2106 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2107 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2108 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2115 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2116 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2118 CR_SET_XER_SO(0, cr_i_zero);
2121 /* ment to randomly to store, we never do! */
2122 CR_SET_XER_SO(0, 0);
2127 CR_SET_XER_SO(0, 0);
2129 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2131 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2138 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2139 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2141 CR_SET_XER_SO(0, cr_i_zero);
2144 /* ment to randomly to store, we never do */
2145 CR_SET_XER_SO(0, 0);
2150 CR_SET_XER_SO(0, 0);
2152 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2154 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2155 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2156 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2157 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2158 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2163 # I.3.3.9 Fixed-Point Arithmetic Instructions
2166 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
2167 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2168 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2169 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2170 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2171 if (RA_is_0) *rT = EXTS(SI);
2172 else *rT = *rA + EXTS(SI);
2173 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2175 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2176 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2177 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2178 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2179 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2180 if (RA_is_0) *rT = EXTS(SI) << 16;
2181 else *rT = *rA + (EXTS(SI) << 16);
2182 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2184 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2185 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2186 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2187 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2188 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2191 ALU_END(*rT, 0/*CA*/, OE, Rc);
2192 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2194 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2195 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2196 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2197 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2198 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2203 ALU_END(*rT, 0/*CA*/, OE, Rc);
2204 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2206 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2207 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2208 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2209 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2210 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2213 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2214 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2216 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2217 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2218 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2219 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2220 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2223 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2224 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
2226 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2227 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2228 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2229 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2230 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2235 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2236 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2238 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2239 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2240 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2241 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2242 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2245 ALU_END(*rT, 1/*CA*/, OE, Rc);
2246 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2248 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2249 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2250 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2251 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2252 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2253 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2258 ALU_END(*rT, 1/*CA*/, OE, Rc);
2259 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2261 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2262 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2263 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2264 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2265 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2269 ALU_END(*rT, 1/*CA*/, OE, Rc);
2270 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2272 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2273 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2274 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2275 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2276 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2281 ALU_END(*rT, 1/*CA*/, OE, Rc);
2282 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2284 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2285 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2286 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2287 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2288 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2292 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2294 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2295 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2296 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2297 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2298 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2303 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2305 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2306 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2307 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2308 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2309 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2312 ALU_END(*rT, 1/*CA*/, OE, Rc);
2313 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2315 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2316 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2317 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2318 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2319 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2323 ALU_END(*rT, 1/*CA*/, OE, Rc);
2324 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2326 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2327 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2328 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2329 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2330 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2334 ALU_END(*rT,0/*CA*/,OE,Rc);
2335 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2337 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2338 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2339 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2340 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2341 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2342 signed_word prod = *rA * EXTS(SI);
2344 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2346 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2348 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2349 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2350 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2351 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2352 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2353 signed64 a = (signed32)(*rA);
2354 signed64 b = (signed32)(*rB);
2355 signed64 prod = a * b;
2356 signed_word t = prod;
2358 if (t != prod && OE)
2359 XER |= (xer_overflow | xer_summary_overflow);
2360 CR0_COMPARE(t, 0, Rc);
2361 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2363 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2365 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2366 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2367 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2368 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2369 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2370 signed64 a = (signed32)(*rA);
2371 signed64 b = (signed32)(*rB);
2372 signed64 prod = a * b;
2373 signed_word t = EXTRACTED64(prod, 0, 31);
2375 CR0_COMPARE(t, 0, Rc);
2376 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2378 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2380 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2381 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2382 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2383 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2384 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2385 unsigned64 a = (unsigned32)(*rA);
2386 unsigned64 b = (unsigned32)(*rB);
2387 unsigned64 prod = a * b;
2388 signed_word t = EXTRACTED64(prod, 0, 31);
2390 CR0_COMPARE(t, 0, Rc);
2391 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2393 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2395 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2396 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2397 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2398 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2399 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2400 signed64 dividend = (signed32)(*rA);
2401 signed64 divisor = (signed32)(*rB);
2402 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2403 || (dividend == 0x80000000 && divisor == -1)) {
2405 XER |= (xer_overflow | xer_summary_overflow);
2406 CR0_COMPARE(0, 0, Rc);
2409 signed64 quotent = dividend / divisor;
2411 CR0_COMPARE((signed_word)quotent, 0, Rc);
2413 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2415 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2417 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2418 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2419 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2420 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2421 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2422 unsigned64 dividend = (unsigned32)(*rA);
2423 unsigned64 divisor = (unsigned32)(*rB);
2426 XER |= (xer_overflow | xer_summary_overflow);
2427 CR0_COMPARE(0, 0, Rc);
2430 unsigned64 quotent = dividend / divisor;
2432 CR0_COMPARE((signed_word)quotent, 0, Rc);
2434 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2438 # I.3.3.10 Fixed-Point Compare Instructions
2441 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2442 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2443 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2444 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2445 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2446 if (!is_64bit_mode && L)
2447 program_interrupt(processor, cia,
2448 illegal_instruction_program_interrupt);
2451 signed_word b = EXTS(SI);
2456 CR_COMPARE(BF, a, b);
2458 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2460 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2461 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2462 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2463 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2464 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2465 if (!is_64bit_mode && L)
2466 program_interrupt(processor, cia,
2467 illegal_instruction_program_interrupt);
2479 CR_COMPARE(BF, a, b);
2481 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2483 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2484 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2485 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2486 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2487 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2488 if (!is_64bit_mode && L)
2489 program_interrupt(processor, cia,
2490 illegal_instruction_program_interrupt);
2493 unsigned_word b = UI;
2495 a = MASKED(*rA, 32, 63);
2498 CR_COMPARE(BF, a, b);
2500 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2502 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2503 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2504 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2505 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2506 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2507 if (!is_64bit_mode && L)
2508 program_interrupt(processor, cia,
2509 illegal_instruction_program_interrupt);
2514 a = MASKED(*rA, 32, 63);
2515 b = MASKED(*rB, 32, 63);
2521 CR_COMPARE(BF, a, b);
2523 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2527 # I.3.3.11 Fixed-Point Trap Instructions
2530 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2532 program_interrupt(processor, cia,
2533 illegal_instruction_program_interrupt);
2535 signed_word a = *rA;
2536 signed_word b = EXTS(SI);
2537 if ((a < b && TO{0})
2539 || (a == b && TO{2})
2540 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2541 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2543 program_interrupt(processor, cia,
2544 trap_program_interrupt);
2547 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2548 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2549 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2550 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2551 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2552 signed_word a = EXTENDED(*rA);
2553 signed_word b = EXTS(SI);
2554 if ((a < b && TO{0})
2556 || (a == b && TO{2})
2557 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2558 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2560 program_interrupt(processor, cia,
2561 trap_program_interrupt);
2563 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2565 program_interrupt(processor, cia,
2566 illegal_instruction_program_interrupt);
2568 signed_word a = *rA;
2569 signed_word b = *rB;
2570 if ((a < b && TO{0})
2572 || (a == b && TO{2})
2573 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2574 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2576 program_interrupt(processor, cia,
2577 trap_program_interrupt);
2580 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2581 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2582 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2583 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2584 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2585 signed_word a = EXTENDED(*rA);
2586 signed_word b = EXTENDED(*rB);
2587 if (TO == 12 && rA == rB) {
2588 ITRACE(trace_breakpoint, ("breakpoint\n"));
2589 cpu_halt(processor, cia, was_trap, 0);
2591 else if ((a < b && TO{0})
2593 || (a == b && TO{2})
2594 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2595 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2597 program_interrupt(processor, cia,
2598 trap_program_interrupt);
2601 # I.3.3.12 Fixed-Point Logical Instructions
2604 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2605 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2606 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2607 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2608 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2610 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2611 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2613 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2614 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2615 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2616 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2617 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2618 *rA = *rS & (UI << 16);
2619 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2620 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2622 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2623 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2624 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2625 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2626 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2628 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2630 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
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
2635 *rA = *rS | (UI << 16);
2636 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2638 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2639 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2640 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2641 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2642 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2644 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2646 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2647 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2648 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2649 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2650 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2651 *rA = *rS ^ (UI << 16);
2652 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2654 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
2655 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2656 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2657 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2658 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2660 CR0_COMPARE(*rA, 0, Rc);
2661 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2663 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
2664 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2665 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2666 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2667 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2669 CR0_COMPARE(*rA, 0, Rc);
2670 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2672 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
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
2678 CR0_COMPARE(*rA, 0, Rc);
2679 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2681 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
2682 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2683 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2684 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2685 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2687 CR0_COMPARE(*rA, 0, Rc);
2688 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2690 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
2691 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2692 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2693 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2694 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2696 CR0_COMPARE(*rA, 0, Rc);
2697 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2699 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
2700 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2701 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2702 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2703 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2704 # *rA = ~(*rS ^ *rB); /* A === B */
2705 # CR0_COMPARE(*rA, 0, Rc);
2707 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
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.412,31.Rc:X:::OR with Complement
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./,21.954,31.Rc:X::extsb:Extend Sign Byte
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 = (signed_word)(signed8)*rS;
2731 CR0_COMPARE(*rA, 0, Rc);
2732 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2734 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
2735 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2736 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2737 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2738 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2739 *rA = (signed_word)(signed16)*rS;
2740 CR0_COMPARE(*rA, 0, Rc);
2741 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2743 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2744 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2745 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2746 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2747 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2748 # *rA = (signed_word)(signed32)*rS;
2749 # CR0_COMPARE(*rA, 0, Rc);
2751 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2753 # unsigned64 mask = BIT64(0);
2754 # unsigned64 source = *rS;
2755 # while (!(source & mask) && mask != 0) {
2760 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2762 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
2763 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2764 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2765 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2766 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2768 unsigned32 mask = BIT32(0);
2769 unsigned32 source = *rS;
2770 while (!(source & mask) && mask != 0) {
2775 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2779 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2782 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
2783 # long n = (sh_5 << 4) | sh_0_4;
2784 # unsigned_word r = ROTL64(*rS, n);
2785 # long b = (mb_5 << 4) | mb_0_4;
2786 # unsigned_word m = MASK(b, 63);
2787 # signed_word result = r & m;
2789 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2791 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
2792 # long n = (sh_5 << 4) | sh_0_4;
2793 # unsigned_word r = ROTL64(*rS, n);
2794 # long e = (me_5 << 4) | me_0_4;
2795 # unsigned_word m = MASK(0, e);
2796 # signed_word result = r & m;
2798 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2800 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
2801 # long n = (sh_5 << 4) | sh_0_4;
2802 # unsigned_word r = ROTL64(*rS, n);
2803 # long b = (mb_5 << 4) | mb_0_4;
2804 # unsigned_word m = MASK(0, (64-n));
2805 # signed_word result = r & m;
2807 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2809 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2810 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2811 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2812 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2813 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2816 unsigned32 r = ROTL32(s, n);
2817 unsigned32 m = MASK(MB+32, ME+32);
2818 signed_word result = r & m;
2820 CR0_COMPARE(result, 0, Rc);
2822 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
2823 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
2824 (unsigned long)result, (unsigned long)CR));
2825 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2827 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2828 # long n = MASKED(*rB, 58, 63);
2829 # unsigned_word r = ROTL64(*rS, n);
2830 # long b = (mb_5 << 4) | mb_0_4;
2831 # unsigned_word m = MASK(b, 63);
2832 # signed_word result = r & m;
2834 # CR0_COMPARE(result, 0, Rc);
2836 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2837 # long n = MASKED(*rB, 58, 63);
2838 # unsigned_word r = ROTL64(*rS, n);
2839 # long e = (me_5 << 4) | me_0_4;
2840 # unsigned_word m = MASK(0, e);
2841 # signed_word result = r & m;
2843 # CR0_COMPARE(result, 0, Rc);
2845 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2846 # long n = MASKED(*rB, 59, 63);
2847 # unsigned32 r = ROTL32(*rS, n);
2848 # unsigned32 m = MASK(MB+32, ME+32);
2849 # signed_word result = r & m;
2851 # CR0_COMPARE(result, 0, Rc);
2853 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
2854 # long n = (sh_5 << 4) | sh_0_4;
2855 # unsigned_word r = ROTL64(*rS, n);
2856 # long b = (mb_5 << 4) | mb_0_4;
2857 # unsigned_word m = MASK(b, (64-n));
2858 # signed_word result = (r & m) | (*rA & ~m)
2860 # CR0_COMPARE(result, 0, Rc);
2862 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2863 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2864 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2865 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2866 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2868 unsigned32 r = ROTL32(*rS, n);
2869 unsigned32 m = MASK(MB+32, ME+32);
2870 signed_word result = (r & m) | (*rA & ~m);
2872 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
2873 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
2874 (unsigned long)result));
2875 CR0_COMPARE(result, 0, Rc);
2876 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2879 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2881 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2882 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2883 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2884 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2885 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2886 int n = MASKED(*rB, 59, 63);
2887 unsigned32 source = *rS;
2888 signed_word shifted;
2890 shifted = (source << n);
2894 CR0_COMPARE(shifted, 0, Rc);
2896 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2897 n, (unsigned long)source, (unsigned long)shifted));
2898 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2900 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
2902 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
2903 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2904 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2905 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2906 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2907 int n = MASKED(*rB, 59, 63);
2908 unsigned32 source = *rS;
2909 signed_word shifted;
2911 shifted = (source >> n);
2915 CR0_COMPARE(shifted, 0, Rc);
2917 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2918 n, (unsigned long)source, (unsigned long)shifted));
2919 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2921 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
2923 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
2924 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2925 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2926 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2927 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2929 signed_word r = ROTL32(*rS, /*64*/32-n);
2930 signed_word m = MASK(n+32, 63);
2931 int S = MASKED(*rS, 32, 32);
2932 signed_word shifted = (r & m) | (S ? ~m : 0);
2934 if (S && ((r & ~m) & MASK(32, 63)) != 0)
2938 CR0_COMPARE(shifted, 0, Rc);
2939 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2941 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
2943 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
2944 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2945 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2946 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2947 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2948 int n = MASKED(*rB, 58, 63);
2949 int shift = (n >= 31 ? 31 : n);
2950 signed32 source = (signed32)*rS; /* signed to keep sign bit */
2951 signed32 shifted = source >> shift;
2952 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
2953 *rA = (signed_word)shifted; /* if 64bit will sign extend */
2954 if (source < 0 && (source & mask))
2958 CR0_COMPARE(shifted, 0, Rc);
2959 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2962 # I.3.3.14 Move to/from System Register Instructions
2965 0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
2966 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2967 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2968 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2969 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
2970 int n = (spr{5:9} << 5) | spr{0:4};
2971 if (spr{0} && IS_PROBLEM_STATE(processor))
2972 program_interrupt(processor, cia,
2973 privileged_instruction_program_interrupt);
2974 else if (!spr_is_valid(n)
2975 || spr_is_readonly(n))
2976 program_interrupt(processor, cia,
2977 illegal_instruction_program_interrupt);
2979 spreg new_val = (spr_length(n) == 64
2981 : MASKED(*rS, 32, 63));
2982 /* HACK - time base registers need to be updated immediatly */
2983 if (WITH_TIME_BASE) {
2986 cpu_set_time_base(processor,
2987 (MASKED64(cpu_get_time_base(processor), 32, 63)
2988 | INSERTED64(new_val, 0, 31)));
2991 cpu_set_time_base(processor,
2992 (MASKED64(cpu_get_time_base(processor), 0, 31)
2993 | INSERTED64(new_val, 32, 63)));
2996 cpu_set_decrementer(processor, new_val);
3007 PPC_INSN_TO_SPR(RS_BITMASK, n);
3009 0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3010 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3011 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3012 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3013 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3014 int n = (spr{5:9} << 5) | spr{0:4};
3015 if (spr{0} && IS_PROBLEM_STATE(processor))
3016 program_interrupt(processor, cia,
3017 privileged_instruction_program_interrupt);
3018 else if (!spr_is_valid(n))
3019 program_interrupt(processor, cia,
3020 illegal_instruction_program_interrupt);
3022 /* HACK - some SPR's need to get their value extracted specially */
3025 PPC_INSN_FROM_SPR(RT_BITMASK, n);
3027 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3028 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3029 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3030 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3031 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3036 unsigned_word mask = 0;
3038 for (f = 0; f < 8; f++) {
3039 if (FXM & (0x80 >> f))
3040 mask |= (0xf << 4*(7-f));
3042 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3044 ppc_insn_mtcr(my_index, processor, cpu_model(processor), rS, FXM);
3046 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3048 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3049 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3050 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3051 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3052 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3053 *rT = (unsigned32)CR;
3054 PPC_INSN_MFCR(RT_BITMASK);
3057 # I.4.6.2 Floating-Point Load Instructions
3060 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3061 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3062 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3063 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3064 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3070 *frT = DOUBLE(MEM(unsigned, EA, 4));
3071 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3073 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3074 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3075 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3076 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3077 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3083 *frT = DOUBLE(MEM(unsigned, EA, 4));
3084 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3086 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
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
3093 program_interrupt(processor, cia,
3094 illegal_instruction_program_interrupt);
3096 *frT = DOUBLE(MEM(unsigned, EA, 4));
3098 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3100 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3101 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3102 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3103 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3104 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3107 program_interrupt(processor, cia,
3108 illegal_instruction_program_interrupt);
3110 *frT = DOUBLE(MEM(unsigned, EA, 4));
3112 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3114 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3115 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3116 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3117 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3118 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3124 *frT = MEM(unsigned, EA, 8);
3125 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3127 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3128 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3129 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3130 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3131 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3137 *frT = MEM(unsigned, EA, 8);
3138 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3140 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
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
3147 program_interrupt(processor, cia,
3148 illegal_instruction_program_interrupt);
3150 *frT = MEM(unsigned, EA, 8);
3152 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3154 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3155 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3156 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3157 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3158 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3161 program_interrupt(processor, cia,
3162 illegal_instruction_program_interrupt);
3164 *frT = MEM(unsigned, EA, 8);
3166 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3170 # I.4.6.3 Floating-Point Store Instructions
3173 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3174 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3175 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3176 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3177 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3183 STORE(EA, 4, SINGLE(*frS));
3184 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3186 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3187 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3188 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3189 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3190 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3196 STORE(EA, 4, SINGLE(*frS));
3197 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3199 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
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
3206 program_interrupt(processor, cia,
3207 illegal_instruction_program_interrupt);
3209 STORE(EA, 4, SINGLE(*frS));
3211 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3213 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3214 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3215 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3216 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3217 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3220 program_interrupt(processor, cia,
3221 illegal_instruction_program_interrupt);
3223 STORE(EA, 4, SINGLE(*frS));
3225 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3227 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3228 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3229 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3230 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3231 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3238 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3240 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3241 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3242 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3243 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3244 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3251 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3253 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
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
3260 program_interrupt(processor, cia,
3261 illegal_instruction_program_interrupt);
3265 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3267 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3268 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3269 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3270 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3271 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3274 program_interrupt(processor, cia,
3275 illegal_instruction_program_interrupt);
3279 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3283 # I.4.6.4 Floating-Point Move Instructions
3286 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3287 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3288 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3289 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3290 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3293 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3295 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3296 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3297 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3298 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3299 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3300 *frT = *frB ^ BIT64(0);
3302 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3304 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3305 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3306 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3307 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3308 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3309 *frT = *frB & ~BIT64(0);
3311 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3313 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3314 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3315 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3316 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3317 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3318 *frT = *frB | BIT64(0);
3320 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3324 # I.4.6.5 Floating-Point Arithmetic Instructions
3327 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3328 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3329 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3330 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3331 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3333 if (is_invalid_operation(processor, cia,
3335 fpscr_vxsnan | fpscr_vxisi,
3338 invalid_arithemetic_operation(processor, cia,
3340 0, /*instruction_is_frsp*/
3341 0, /*instruction_is_convert_to_64bit*/
3342 0, /*instruction_is_convert_to_32bit*/
3343 0); /*single-precision*/
3347 double s = *(double*)frA + *(double*)frB;
3351 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3353 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
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 1); /*single-precision*/
3373 float s = *(double*)frA + *(double*)frB;
3377 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3379 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
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 0); /*single-precision*/
3399 double s = *(double*)frA - *(double*)frB;
3403 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3405 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
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 1); /*single-precision*/
3425 float s = *(double*)frA - *(double*)frB;
3429 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3431 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3432 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3433 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3434 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3435 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3437 if (is_invalid_operation(processor, cia,
3439 fpscr_vxsnan | fpscr_vximz,
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 0); /*single-precision*/
3451 double s = *(double*)frA * *(double*)frC;
3455 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3457 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3458 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3459 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3460 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 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 1); /*single-precision*/
3477 float s = *(double*)frA * *(double*)frC;
3481 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3483 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3484 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3485 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3486 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3487 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3489 if (is_invalid_operation(processor, cia,
3491 fpscr_vxsnan | fpscr_vxzdz,
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 0); /*single-precision*/
3503 double s = *(double*)frA / *(double*)frB;
3507 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3509 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3510 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3511 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3512 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3513 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 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 1); /*single-precision*/
3529 float s = *(double*)frA / *(double*)frB;
3533 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3535 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3536 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3537 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3538 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3539 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3541 double product; /*HACK! - incorrectly loosing precision ... */
3542 /* compute the multiply */
3543 if (is_invalid_operation(processor, cia,
3545 fpscr_vxsnan | fpscr_vximz,
3548 invalid_arithemetic_operation(processor, cia,
3549 (unsigned64*)&product, *frA, 0, *frC,
3550 0, /*instruction_is_frsp*/
3551 0, /*instruction_is_convert_to_64bit*/
3552 0, /*instruction_is_convert_to_32bit*/
3553 0); /*single-precision*/
3557 product = *(double*)frA * *(double*)frC;
3559 /* compute the add */
3560 if (is_invalid_operation(processor, cia,
3562 fpscr_vxsnan | fpscr_vxisi,
3565 invalid_arithemetic_operation(processor, cia,
3566 frT, product, *frB, 0,
3567 0, /*instruction_is_frsp*/
3568 0, /*instruction_is_convert_to_64bit*/
3569 0, /*instruction_is_convert_to_32bit*/
3570 0); /*single-precision*/
3574 double s = product + *(double*)frB;
3578 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3580 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3581 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3582 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3583 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3584 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3586 float product; /*HACK! - incorrectly loosing precision ... */
3587 /* compute the multiply */
3588 if (is_invalid_operation(processor, cia,
3590 fpscr_vxsnan | fpscr_vximz,
3593 invalid_arithemetic_operation(processor, cia,
3594 (unsigned64*)&product, *frA, 0, *frC,
3595 0, /*instruction_is_frsp*/
3596 0, /*instruction_is_convert_to_64bit*/
3597 0, /*instruction_is_convert_to_32bit*/
3598 0); /*single-precision*/
3602 product = *(double*)frA * *(double*)frC;
3604 /* compute the add */
3605 if (is_invalid_operation(processor, cia,
3607 fpscr_vxsnan | fpscr_vxisi,
3610 invalid_arithemetic_operation(processor, cia,
3611 frT, product, *frB, 0,
3612 0, /*instruction_is_frsp*/
3613 0, /*instruction_is_convert_to_64bit*/
3614 0, /*instruction_is_convert_to_32bit*/
3615 0); /*single-precision*/
3619 float s = product + *(double*)frB;
3620 *(double*)frT = (double)s;
3623 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3625 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3626 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3627 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3628 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3629 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3631 double product; /*HACK! - incorrectly loosing precision ... */
3632 /* compute the multiply */
3633 if (is_invalid_operation(processor, cia,
3635 fpscr_vxsnan | fpscr_vximz,
3638 invalid_arithemetic_operation(processor, cia,
3639 (unsigned64*)&product, *frA, 0, *frC,
3640 0, /*instruction_is_frsp*/
3641 0, /*instruction_is_convert_to_64bit*/
3642 0, /*instruction_is_convert_to_32bit*/
3643 0); /*single-precision*/
3647 product = *(double*)frA * *(double*)frC;
3649 /* compute the subtract */
3650 if (is_invalid_operation(processor, cia,
3652 fpscr_vxsnan | fpscr_vxisi,
3655 invalid_arithemetic_operation(processor, cia,
3656 frT, product, *frB, 0,
3657 0, /*instruction_is_frsp*/
3658 0, /*instruction_is_convert_to_64bit*/
3659 0, /*instruction_is_convert_to_32bit*/
3660 0); /*single-precision*/
3664 double s = product - *(double*)frB;
3668 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3670 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
3671 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3672 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3673 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3674 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3676 float product; /*HACK! - incorrectly loosing precision ... */
3677 /* compute the multiply */
3678 if (is_invalid_operation(processor, cia,
3680 fpscr_vxsnan | fpscr_vximz,
3683 invalid_arithemetic_operation(processor, cia,
3684 (unsigned64*)&product, *frA, 0, *frC,
3685 0, /*instruction_is_frsp*/
3686 0, /*instruction_is_convert_to_64bit*/
3687 0, /*instruction_is_convert_to_32bit*/
3688 0); /*single-precision*/
3692 product = *(double*)frA * *(double*)frC;
3694 /* compute the subtract */
3695 if (is_invalid_operation(processor, cia,
3697 fpscr_vxsnan | fpscr_vxisi,
3700 invalid_arithemetic_operation(processor, cia,
3701 frT, product, *frB, 0,
3702 0, /*instruction_is_frsp*/
3703 0, /*instruction_is_convert_to_64bit*/
3704 0, /*instruction_is_convert_to_32bit*/
3705 0); /*single-precision*/
3709 float s = product - *(double*)frB;
3710 *(double*)frT = (double)s;
3713 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3715 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
3716 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3717 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3718 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3719 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3721 double product; /*HACK! - incorrectly loosing precision ... */
3722 /* compute the multiply */
3723 if (is_invalid_operation(processor, cia,
3725 fpscr_vxsnan | fpscr_vximz,
3728 invalid_arithemetic_operation(processor, cia,
3729 (unsigned64*)&product, *frA, 0, *frC,
3730 0, /*instruction_is_frsp*/
3731 0, /*instruction_is_convert_to_64bit*/
3732 0, /*instruction_is_convert_to_32bit*/
3733 0); /*single-precision*/
3737 product = *(double*)frA * *(double*)frC;
3739 /* compute the add */
3740 if (is_invalid_operation(processor, cia,
3742 fpscr_vxsnan | fpscr_vxisi,
3745 invalid_arithemetic_operation(processor, cia,
3746 frT, product, *frB, 0,
3747 0, /*instruction_is_frsp*/
3748 0, /*instruction_is_convert_to_64bit*/
3749 0, /*instruction_is_convert_to_32bit*/
3750 0); /*single-precision*/
3754 double s = -(product + *(double*)frB);
3758 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3760 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
3761 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3762 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3763 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3764 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3766 float product; /*HACK! - incorrectly loosing precision ... */
3767 /* compute the multiply */
3768 if (is_invalid_operation(processor, cia,
3770 fpscr_vxsnan | fpscr_vximz,
3773 invalid_arithemetic_operation(processor, cia,
3774 (unsigned64*)&product, *frA, 0, *frC,
3775 0, /*instruction_is_frsp*/
3776 0, /*instruction_is_convert_to_64bit*/
3777 0, /*instruction_is_convert_to_32bit*/
3778 0); /*single-precision*/
3782 product = *(double*)frA * *(double*)frC;
3784 /* compute the add */
3785 if (is_invalid_operation(processor, cia,
3787 fpscr_vxsnan | fpscr_vxisi,
3790 invalid_arithemetic_operation(processor, cia,
3791 frT, product, *frB, 0,
3792 0, /*instruction_is_frsp*/
3793 0, /*instruction_is_convert_to_64bit*/
3794 0, /*instruction_is_convert_to_32bit*/
3795 0); /*single-precision*/
3799 float s = -(product + *(double*)frB);
3800 *(double*)frT = (double)s;
3803 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3805 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
3806 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3807 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3808 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3809 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3811 double product; /*HACK! - incorrectly loosing precision ... */
3812 /* compute the multiply */
3813 if (is_invalid_operation(processor, cia,
3815 fpscr_vxsnan | fpscr_vximz,
3818 invalid_arithemetic_operation(processor, cia,
3819 (unsigned64*)&product, *frA, 0, *frC,
3820 0, /*instruction_is_frsp*/
3821 0, /*instruction_is_convert_to_64bit*/
3822 0, /*instruction_is_convert_to_32bit*/
3823 0); /*single-precision*/
3827 product = *(double*)frA * *(double*)frC;
3829 /* compute the subtract */
3830 if (is_invalid_operation(processor, cia,
3832 fpscr_vxsnan | fpscr_vxisi,
3835 invalid_arithemetic_operation(processor, cia,
3836 frT, product, *frB, 0,
3837 0, /*instruction_is_frsp*/
3838 0, /*instruction_is_convert_to_64bit*/
3839 0, /*instruction_is_convert_to_32bit*/
3840 0); /*single-precision*/
3844 double s = -(product - *(double*)frB);
3848 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3850 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
3851 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3852 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3853 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3854 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3856 float product; /*HACK! - incorrectly loosing precision ... */
3857 /* compute the multiply */
3858 if (is_invalid_operation(processor, cia,
3860 fpscr_vxsnan | fpscr_vximz,
3863 invalid_arithemetic_operation(processor, cia,
3864 (unsigned64*)&product, *frA, 0, *frC,
3865 0, /*instruction_is_frsp*/
3866 0, /*instruction_is_convert_to_64bit*/
3867 0, /*instruction_is_convert_to_32bit*/
3868 0); /*single-precision*/
3872 product = *(double*)frA * *(double*)frC;
3874 /* compute the subtract */
3875 if (is_invalid_operation(processor, cia,
3877 fpscr_vxsnan | fpscr_vxisi,
3880 invalid_arithemetic_operation(processor, cia,
3881 frT, product, *frB, 0,
3882 0, /*instruction_is_frsp*/
3883 0, /*instruction_is_convert_to_64bit*/
3884 0, /*instruction_is_convert_to_32bit*/
3885 0); /*single-precision*/
3889 float s = -(product - *(double*)frB);
3890 *(double*)frT = (double)s;
3893 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3897 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
3900 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
3901 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3902 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3903 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3904 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3907 unsigned64 frac_grx;
3908 /* split off cases for what to do */
3909 if (EXTRACTED64(*frB, 1, 11) < 897
3910 && EXTRACTED64(*frB, 1, 63) > 0) {
3911 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
3912 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
3914 if (EXTRACTED64(*frB, 1, 11) > 1150
3915 && EXTRACTED64(*frB, 1, 11) < 2047) {
3916 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3917 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
3919 if (EXTRACTED64(*frB, 1, 11) > 896
3920 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
3921 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
3922 if (EXTRACTED64(*frB, 1, 11) == 2047) {
3923 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
3924 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
3925 if (EXTRACTED64(*frB, 12, 12) == 0
3926 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
3929 Disabled_Exponent_Underflow:
3930 sign = EXTRACTED64(*frB, 0, 0);
3931 if (EXTRACTED64(*frB, 1, 11) == 0) {
3933 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3935 if (EXTRACTED64(*frB, 1, 11) > 0) {
3936 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3937 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3939 /* G|R|X == zero from above */
3940 while (exp < -126) {
3942 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
3943 | MASKED64(frac_grx, 55, 55));
3945 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
3946 Round_Single(processor, sign, &exp, &frac_grx);
3947 FPSCR_SET_XX(FPSCR & fpscr_fi);
3948 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
3949 *frT = INSERTED64(sign, 0, 0);
3950 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3951 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3953 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
3954 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
3955 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3956 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3958 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
3959 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
3960 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
3962 /*Normalize_Operand:*/
3963 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3965 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3967 *frT = (INSERTED64(sign, 0, 0)
3968 | INSERTED64(exp + 1023, 1, 11)
3969 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3972 Enabled_Exponent_Underflow:
3974 sign = EXTRACTED64(*frB, 0, 0);
3975 if (EXTRACTED64(*frB, 1, 11) == 0) {
3977 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3979 if (EXTRACTED64(*frB, 1, 11) > 0) {
3980 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3981 frac_grx = (BIT64(0) |
3982 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
3984 /*Normalize_Operand:*/
3985 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3987 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3989 Round_Single(processor, sign, &exp, &frac_grx);
3990 FPSCR_SET_XX(FPSCR & fpscr_fi);
3992 *frT = (INSERTED64(sign, 0, 0)
3993 | INSERTED64(exp + 1023, 1, 11)
3994 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3995 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3996 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3998 Disabled_Exponent_Overflow:
4000 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4001 if (EXTRACTED64(*frB, 0, 0) == 0) {
4002 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4003 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4005 if (EXTRACTED64(*frB, 0, 0) == 1) {
4006 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4007 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4010 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4011 if (EXTRACTED64(*frB, 0, 0) == 0) {
4012 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4013 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4015 if (EXTRACTED64(*frB, 0, 0) == 1) {
4016 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4017 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4020 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4021 if (EXTRACTED64(*frB, 0, 0) == 0) {
4022 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4023 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4025 if (EXTRACTED64(*frB, 0, 0) == 1) {
4026 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4027 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4030 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4031 if (EXTRACTED64(*frB, 0, 0) == 0) {
4032 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4033 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4035 if (EXTRACTED64(*frB, 0, 0) == 1) {
4036 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4037 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4040 /* FPSCR[FR] <- undefined */
4044 Enabled_Exponent_Overflow:
4045 sign = EXTRACTED64(*frB, 0, 0);
4046 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4047 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4048 Round_Single(processor, sign, &exp, &frac_grx);
4049 FPSCR_SET_XX(FPSCR & fpscr_fi);
4053 *frT = (INSERTED64(sign, 0, 0)
4054 | INSERTED64(exp + 1023, 1, 11)
4055 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4056 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4057 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4061 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4062 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4068 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4069 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4074 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4075 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4080 FPSCR_OR_VX(fpscr_vxsnan);
4081 if ((FPSCR & fpscr_ve) == 0) {
4082 *frT = (MASKED64(*frB, 0, 11)
4084 | MASKED64(*frB, 13, 34));
4085 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4091 sign = EXTRACTED64(*frB, 0, 0);
4092 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4093 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4094 Round_Single(processor, sign, &exp, &frac_grx);
4095 FPSCR_SET_XX(FPSCR & fpscr_fi);
4096 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4097 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4098 *frT = (INSERTED64(sign, 0, 0)
4099 | INSERTED64(exp + 1023, 1, 11)
4100 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4101 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4102 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4105 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4107 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4109 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4111 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4113 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4114 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4115 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4116 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4117 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4119 convert_to_integer(processor, cia,
4121 fpscr_rn_round_towards_zero, 32);
4123 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4125 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4126 int sign = EXTRACTED64(*frB, 0, 0);
4128 unsigned64 frac = *frB;
4129 if (frac == 0) goto Zero_Operand;
4130 if (sign == 1) frac = ~frac + 1;
4131 while (EXTRACTED64(frac, 0, 0) == 0) {
4132 /*??? do the loop 0 times if (FRB) = max negative integer */
4133 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4136 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4137 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4138 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4139 *frT = (INSERTED64(sign, 0, 0)
4140 | INSERTED64(exp + 1023, 1, 11)
4141 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4147 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4152 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4155 # I.4.6.7 Floating-Point Compare Instructions
4158 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4159 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4160 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4161 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4162 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4165 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4166 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4167 else if (is_less_than(frA, frB))
4168 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4169 else if (is_greater_than(frA, frB))
4170 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4172 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4174 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4175 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4176 FPSCR_OR_VX(fpscr_vxsnan);
4178 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4180 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4181 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4182 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4183 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4184 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4187 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4188 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4189 else if (is_less_than(frA, frB))
4190 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4191 else if (is_greater_than(frA, frB))
4192 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4194 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4196 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4197 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4198 FPSCR_OR_VX(fpscr_vxsnan);
4199 if ((FPSCR & fpscr_ve) == 0)
4200 FPSCR_OR_VX(fpscr_vxvc);
4202 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4203 FPSCR_OR_VX(fpscr_vxvc);
4206 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4210 # I.4.6.8 Floating-Point Status and Control Register Instructions
4213 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4215 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4217 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4219 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4221 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4223 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4227 # I.A.1.1 Floating-Point Store Instruction
4229 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4232 # I.A.1.2 Floating-Point Arithmetic Instructions
4235 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
4237 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4239 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
4241 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4244 # I.A.1.3 Floating-Point Select Instruction
4247 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4251 # II.3.2 Cache Management Instructions
4254 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4255 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4256 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4257 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4258 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4259 /* blindly flush all instruction cache entries */
4260 #if WITH_IDECODE_CACHE_SIZE
4261 cpu_flush_icache(processor);
4263 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4265 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4266 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4267 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4268 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4269 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4270 cpu_synchronize_context(processor);
4271 PPC_INSN_INT(0, 0, 0);
4275 # II.3.2.2 Data Cache Instructions
4278 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4279 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4280 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4281 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4282 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4283 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4284 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4286 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4287 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4288 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4289 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4290 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4291 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4292 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4294 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4295 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4296 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4297 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4298 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4299 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4300 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4302 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4303 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4304 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4305 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4306 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4307 TRACE(trace_tbd,("Data Cache Block Store\n"));
4308 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4310 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4311 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4312 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4313 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4314 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4315 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4316 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4319 # II.3.3 Enforce In-order Execution of I/O Instruction
4322 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4323 /* Since this model has no instruction overlap
4324 this instruction need do nothing */
4327 # II.4.1 Time Base Instructions
4330 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4331 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4332 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4333 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4334 int n = (tbr{5:9} << 5) | tbr{0:4};
4336 if (is_64bit_implementation) *rT = TB;
4337 else *rT = EXTRACTED64(TB, 32, 63);
4339 else if (n == 269) {
4340 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4341 else *rT = EXTRACTED64(TB, 0, 31);
4344 program_interrupt(processor, cia,
4345 illegal_instruction_program_interrupt);
4349 # III.2.3.1 System Linkage Instructions
4352 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4353 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4354 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4355 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4356 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4357 if (IS_PROBLEM_STATE(processor)) {
4358 program_interrupt(processor, cia,
4359 privileged_instruction_program_interrupt);
4362 MSR = (MASKED(SRR1, 0, 32)
4363 | MASKED(SRR1, 37, 41)
4364 | MASKED(SRR1, 48, 63));
4365 NIA = MASKED(SRR0, 0, 61);
4366 cpu_synchronize_context(processor);
4370 # III.3.4.1 Move to/from System Register Instructions
4373 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
4374 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
4375 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4376 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4377 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4378 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4379 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4380 if (IS_PROBLEM_STATE(processor))
4381 program_interrupt(processor, cia,
4382 privileged_instruction_program_interrupt);
4386 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4387 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4388 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4389 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4390 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4391 if (IS_PROBLEM_STATE(processor))
4392 program_interrupt(processor, cia,
4393 privileged_instruction_program_interrupt);
4399 # III.4.11.1 Cache Management Instructions
4402 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4403 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4404 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4405 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4406 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4407 if (IS_PROBLEM_STATE(processor))
4408 program_interrupt(processor, cia,
4409 privileged_instruction_program_interrupt);
4411 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4414 # III.4.11.2 Segment Register Manipulation Instructions
4417 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4418 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4419 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4420 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4421 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4422 if (IS_PROBLEM_STATE(processor))
4423 program_interrupt(processor, cia,
4424 privileged_instruction_program_interrupt);
4428 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4429 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4430 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4431 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4432 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4433 if (IS_PROBLEM_STATE(processor))
4434 program_interrupt(processor, cia,
4435 privileged_instruction_program_interrupt);
4437 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4439 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4440 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4441 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4442 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4443 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4444 if (IS_PROBLEM_STATE(processor))
4445 program_interrupt(processor, cia,
4446 privileged_instruction_program_interrupt);
4450 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4451 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4452 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4453 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4454 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4455 if (IS_PROBLEM_STATE(processor))
4456 program_interrupt(processor, cia,
4457 privileged_instruction_program_interrupt);
4459 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4463 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4466 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4468 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4470 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4472 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4474 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4478 # III.A.1.2 External Access Instructions
4481 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4483 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed