2 # This file is part of the program psim.
4 # Copyright 1994, 1995, 1996, 1997, 2003, 2004 Andrew Cagney
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 3 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, see <http://www.gnu.org/licenses/>.
37 :cache:::signed_word *:rA:RA:(cpu_registers(processor)->gpr + RA)
38 :cache:::uint32_t:RA_BITMASK:RA:(1 << RA)
39 :compute:::int:RA_is_0:RA:(RA == 0)
41 :cache:::signed_word *:rT:RT:(cpu_registers(processor)->gpr + RT)
42 :cache:::uint32_t:RT_BITMASK:RT:(1 << RT)
44 :cache:::signed_word *:rS:RS:(cpu_registers(processor)->gpr + RS)
45 :cache:::uint32_t:RS_BITMASK:RS:(1 << RS)
47 :cache:::signed_word *:rB:RB:(cpu_registers(processor)->gpr + RB)
48 :cache:::uint32_t:RB_BITMASK:RB:(1 << RB)
50 :cache:::uint64_t *:frA:FRA:(cpu_registers(processor)->fpr + FRA)
51 :cache:::uint32_t:FRA_BITMASK:FRA:(1 << FRA)
53 :cache:::uint64_t *:frB:FRB:(cpu_registers(processor)->fpr + FRB)
54 :cache:::uint32_t:FRB_BITMASK:FRB:(1 << FRB)
56 :cache:::uint64_t *:frC:FRC:(cpu_registers(processor)->fpr + FRC)
57 :cache:::uint32_t:FRC_BITMASK:FRC:(1 << FRC)
59 :cache:::uint64_t *:frS:FRS:(cpu_registers(processor)->fpr + FRS)
60 :cache:::uint32_t:FRS_BITMASK:FRS:(1 << FRS)
62 :cache:::uint64_t *:frT:FRT:(cpu_registers(processor)->fpr + FRT)
63 :cache:::uint32_t:FRT_BITMASK:FRT:(1 << FRT)
64 :cache:::unsigned_word:EXTS_SI:SI:((signed_word)(int16_t)instruction)
66 :cache::::BIT32_BI:BI:BIT32(BI)
68 :cache:::uint32_t:BF_BITMASK:BF:(1 << BF)
70 :cache::::BIT32_BA:BA:BIT32(BA)
71 :cache:::uint32_t:BA_BITMASK:BA:(1 << BA)
73 :cache::::BIT32_BB:BB:BIT32(BB)
74 :cache:::uint32_t:BB_BITMASK:BB:(1 << BB)
76 :cache:::uint32_t:BT_BITMASK:BT:(1 << BT)
77 :cache:::unsigned_word:EXTS_BD_0b00:BD:(((signed_word)(int16_t)instruction) & ~3)
78 :cache:::unsigned_word:EXTS_LI_0b00:LI:((((signed_word)(int32_t)(instruction << 6)) >> 6) & ~0x3)
79 :cache:::unsigned_word:EXTS_D:D:((signed_word)(int16_t)(instruction))
80 :cache:::unsigned_word:EXTS_DS_0b00:DS:(((signed_word)(int16_t)instruction) & ~0x3)
81 #:compute:::int:SPR_is_256:SPR:(SPR == 256)
84 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
85 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
86 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
87 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
91 #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \
93 if (CURRENT_MODEL_ISSUE > 0) { \
95 ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
97 ppc_insn_int(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
101 #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \
103 if (CURRENT_MODEL_ISSUE > 0) \
104 ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
107 #define PPC_INSN_CR(OUT_MASK, IN_MASK) \
109 if (CURRENT_MODEL_ISSUE > 0) \
110 ppc_insn_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
113 #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \
115 if (CURRENT_MODEL_ISSUE > 0) { \
117 ppc_insn_float(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \
119 ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
123 #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \
125 if (CURRENT_MODEL_ISSUE > 0) \
126 ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
129 #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \
131 if (CURRENT_MODEL_ISSUE > 0) \
132 ppc_insn_int_float(MY_INDEX, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \
135 #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \
137 if (CURRENT_MODEL_ISSUE > 0) \
138 ppc_insn_from_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
141 #define PPC_INSN_TO_SPR(INT_MASK, SPR) \
143 if (CURRENT_MODEL_ISSUE > 0) \
144 ppc_insn_to_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \
147 #define PPC_INSN_MFCR(INT_MASK) \
149 if (CURRENT_MODEL_ISSUE > 0) \
150 ppc_insn_mfcr(MY_INDEX, cpu_model(processor), INT_MASK); \
153 #define PPC_INSN_MTCR(INT_MASK, FXM) \
155 if (CURRENT_MODEL_ISSUE > 0) \
156 ppc_insn_mtcr(MY_INDEX, cpu_model(processor), INT_MASK, FXM); \
160 typedef enum _ppc_function_unit {
161 PPC_UNIT_BAD, /* unknown function unit */
162 PPC_UNIT_IU, /* integer unit (601/603 style) */
163 PPC_UNIT_SRU, /* system register unit (601/603 style) */
164 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
165 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
166 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
167 PPC_UNIT_FPU, /* floating point unit */
168 PPC_UNIT_LSU, /* load/store unit */
169 PPC_UNIT_BPU, /* branch unit */
170 nr_ppc_function_units
173 /* Structure to hold timing information on a per instruction basis */
175 ppc_function_unit first_unit; /* first functional unit this insn could use */
176 ppc_function_unit second_unit; /* second functional unit this insn could use */
177 int16_t issue; /* # cycles before function unit can process other insns */
178 int16_t done; /* # cycles before insn is done */
179 uint32_t flags; /* any flags that are needed */
182 /* Register mappings in status masks */
183 #define PPC_CR_REG 0 /* start of CR0 .. CR7 */
184 #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */
186 #define PPC_NO_SPR (-1) /* flag for no SPR register */
188 /* Return if 1 bit set */
189 #define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0)
191 /* Structure for each functional unit that is busy */
192 typedef struct _model_busy model_busy;
194 model_busy *next; /* next function unit */
195 ppc_function_unit unit; /* function unit name */
196 uint32_t int_busy; /* int registers that are busy */
197 uint32_t fp_busy; /* floating point registers that are busy */
198 uint32_t cr_fpscr_busy; /* CR/FPSCR registers that are busy */
199 int16_t spr_busy; /* SPR register that is busy or PPC_NO_SPR */
200 uint32_t vr_busy; /* AltiVec registers that are busy */
201 int16_t vscr_busy; /* AltiVec status register busy */
202 int16_t issue; /* # of cycles until unit can accept another insn */
203 int16_t done; /* # of cycles until insn is done */
204 int16_t nr_writebacks; /* # of registers this unit writes back */
207 /* Structure to hold the current state information for the simulated CPU model */
209 cpu *processor; /* point back to processor */
210 const char *name; /* model name */
211 const model_time *timing; /* timing information */
212 model_busy busy_head; /* dummy entry to head list of busy function units */
213 model_busy *busy_tail; /* tail of list of busy function units */
214 model_busy *free_list; /* list of model_busy structs not in use */
215 count_type nr_cycles; /* # cycles */
216 count_type nr_branches; /* # branches */
217 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
218 count_type nr_branch_predict_trues; /* # branches predicted correctly */
219 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
220 count_type nr_branch_conditional[32]; /* # of each type of bc */
221 count_type nr_mtcrf_crs[9]; /* # of CR's moved in a mtcrf instruction */
222 count_type nr_stalls_data; /* # of stalls for data */
223 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
224 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
225 count_type nr_stalls_writeback; /* # of stalls waiting for a writeback slot */
226 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
227 int max_nr_writebacks; /* max # of writeback slots available */
228 uint32_t int_busy; /* int registers that are busy */
229 uint32_t fp_busy; /* floating point registers that are busy */
230 uint32_t cr_fpscr_busy; /* CR/FPSCR registers that are busy */
231 uint8_t spr_busy[nr_of_sprs]; /* SPR registers that are busy */
232 uint32_t vr_busy; /* AltiVec registers that are busy */
233 uint8_t vscr_busy; /* AltiVec SC register busy */
234 uint8_t busy[nr_ppc_function_units]; /* whether a function is busy or not */
237 static const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
238 "unknown functional unit instruction",
239 "integer functional unit instruction",
240 "system register functional unit instruction",
241 "1st single cycle integer functional unit instruction",
242 "2nd single cycle integer functional unit instruction",
243 "multiple cycle integer functional unit instruction",
244 "floating point functional unit instruction",
245 "load/store functional unit instruction",
246 "branch functional unit instruction",
249 static const char *const ppc_branch_conditional_name[32] = {
250 "branch if --CTR != 0 and condition is FALSE", /* 0000y */
251 "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
252 "branch if --CTR == 0 and condition is FALSE", /* 0001y */
253 "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
254 "branch if the condition is FALSE", /* 001zy */
255 "branch if the condition is FALSE, reverse branch likely",
256 "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */
257 "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
258 "branch if --CTR != 0 and condition is TRUE", /* 0100y */
259 "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
260 "branch if --CTR == 0 and condition is TRUE", /* 0101y */
261 "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
262 "branch if the condition is TRUE", /* 011zy */
263 "branch if the condition is TRUE, reverse branch likely",
264 "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */
265 "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
266 "branch if --CTR != 0", /* 1z00y */
267 "branch if --CTR != 0, reverse branch likely",
268 "branch if --CTR == 0", /* 1z01y */
269 "branch if --CTR == 0, reverse branch likely",
270 "branch always", /* 1z1zz */
271 "branch always (ignored bit 5 set to 1)",
272 "branch always (ignored bit 4 set to 1)", /* 1z1zz */
273 "branch always (ignored bits 4,5 set to 1)",
274 "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */
275 "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
276 "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */
277 "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
278 "branch always (ignored bit 1 set to 1)", /* 1z1zz */
279 "branch always (ignored bits 1,5 set to 1)",
280 "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */
281 "branch always (ignored bits 1,4,5 set to 1)",
284 static const char *const ppc_nr_mtcrf_crs[9] = {
285 "mtcrf moving 0 CRs",
287 "mtcrf moving 2 CRs",
288 "mtcrf moving 3 CRs",
289 "mtcrf moving 4 CRs",
290 "mtcrf moving 5 CRs",
291 "mtcrf moving 6 CRs",
292 "mtcrf moving 7 CRs",
293 "mtcrf moving all CRs",
296 # Trace releasing resources
297 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
299 TRACE(trace_model,("done, %s, %d writeback%s\n", ppc_function_unit_name[busy->unit],
300 busy->nr_writebacks, busy->nr_writebacks == 1 ? "" : "s"));
301 if (busy->int_busy) {
302 for(i = 0; i < 32; i++) {
303 if (((1 << i) & busy->int_busy) != 0) {
304 TRACE(trace_model, ("Register r%d is now available.\n", i));
309 for(i = 0; i < 32; i++) {
310 if (((1 << i) & busy->fp_busy) != 0) {
311 TRACE(trace_model, ("Register f%d is now available.\n", i));
315 if (busy->cr_fpscr_busy) {
316 for(i = 0; i < 8; i++) {
317 if (((1 << i) & busy->cr_fpscr_busy) != 0) {
318 TRACE(trace_model, ("Register cr%d is now available.\n", i));
321 if (busy->cr_fpscr_busy & 0x100)
322 TRACE(trace_model, ("Register fpscr is now available.\n"));
324 if (busy->spr_busy != PPC_NO_SPR)
325 TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
327 for(i = 0; i < 32; i++) {
328 if (((1 << i) & busy->vr_busy) != 0) {
329 TRACE(trace_model, ("Register v%d is now available.\n", i));
334 TRACE(trace_model, ("VSCR Register %s is now available.\n", spr_name(busy->spr_busy)));
336 # Trace making registers busy
337 void::model-static::model_trace_make_busy:model_data *model_ptr, uint32_t int_mask, uint32_t fp_mask, uint32_t cr_mask
340 for(i = 0; i < 32; i++) {
341 if (((1 << i) & int_mask) != 0) {
342 TRACE(trace_model, ("Register r%d is now busy.\n", i));
347 for(i = 0; i < 32; i++) {
348 if (((1 << i) & fp_mask) != 0) {
349 TRACE(trace_model, ("Register f%d is now busy.\n", i));
354 for(i = 0; i < 8; i++) {
355 if (((1 << i) & cr_mask) != 0) {
356 TRACE(trace_model, ("Register cr%d is now busy.\n", i));
361 # Trace waiting for registers to become available
362 void::model-static::model_trace_busy_p:model_data *model_ptr, uint32_t int_busy, uint32_t fp_busy, uint32_t cr_or_fpscr_busy, int spr_busy
365 int_busy &= model_ptr->int_busy;
366 for(i = 0; i < 32; i++) {
367 if (((1 << i) & int_busy) != 0) {
368 TRACE(trace_model, ("Waiting for register r%d.\n", i));
373 fp_busy &= model_ptr->fp_busy;
374 for(i = 0; i < 32; i++) {
375 if (((1 << i) & fp_busy) != 0) {
376 TRACE(trace_model, ("Waiting for register f%d.\n", i));
380 if (cr_or_fpscr_busy) {
381 cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
382 for(i = 0; i < 8; i++) {
383 if (((1 << i) & cr_or_fpscr_busy) != 0) {
384 TRACE(trace_model, ("Waiting for register cr%d.\n", i));
387 if (cr_or_fpscr_busy & 0x100)
388 TRACE(trace_model, ("Waiting for register fpscr.\n"));
390 if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
391 TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
393 # Advance state to next cycle, releasing any registers allocated
394 void::model-internal::model_new_cycle:model_data *model_ptr
395 model_busy *cur_busy = model_ptr->busy_head.next;
396 model_busy *free_list = model_ptr->free_list;
397 model_busy *busy_tail = &model_ptr->busy_head;
398 int nr_writebacks = model_ptr->max_nr_writebacks;
401 model_ptr->nr_cycles++;
402 TRACE(trace_model,("New cycle %lu\n", (unsigned long)model_ptr->nr_cycles));
403 for ( ; cur_busy; cur_busy = next) {
404 next = cur_busy->next;
405 if (--cur_busy->done <= 0) { /* function unit done, release registers if we have writeback slots */
406 nr_writebacks -= cur_busy->nr_writebacks;
407 if (nr_writebacks >= 0) {
408 model_ptr->int_busy &= ~cur_busy->int_busy;
409 model_ptr->fp_busy &= ~cur_busy->fp_busy;
410 model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
411 if (cur_busy->spr_busy != PPC_NO_SPR)
412 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
413 model_ptr->vr_busy &= ~cur_busy->vr_busy;
414 model_ptr->vscr_busy = ~cur_busy->vscr_busy;
416 if (WITH_TRACE && ppc_trace[trace_model])
417 model_trace_release(model_ptr, cur_busy);
419 model_ptr->busy[cur_busy->unit] = 0;
420 cur_busy->next = free_list;
421 free_list = cur_busy;
423 else { /* writeback slots not available */
424 TRACE(trace_model,("%d writeback slot%s not available for %s\n",
425 cur_busy->nr_writebacks,
426 cur_busy->nr_writebacks == 1 ? " is" : "s are",
427 ppc_function_unit_name[cur_busy->unit]));
428 cur_busy->done++; /* undo -- above */
429 model_ptr->nr_stalls_writeback++;
430 busy_tail->next = cur_busy;
431 busy_tail = cur_busy;
434 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
435 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
436 model_ptr->busy[cur_busy->unit] = 0;
437 busy_tail->next = cur_busy;
438 busy_tail = cur_busy;
441 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
442 ppc_function_unit_name[cur_busy->unit],
445 busy_tail->next = cur_busy;
446 busy_tail = cur_busy;
450 busy_tail->next = (model_busy *)0;
451 model_ptr->busy_tail = busy_tail;
452 model_ptr->free_list = free_list;
454 # Mark a function unit as busy, return the busy structure
455 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
458 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
460 if (!model_ptr->free_list) {
461 busy = ZALLOC(model_busy);
464 busy = model_ptr->free_list;
465 model_ptr->free_list = busy->next;
466 busy->next = (model_busy *)0;
469 busy->cr_fpscr_busy = 0;
470 busy->nr_writebacks = 0;
478 busy->spr_busy = PPC_NO_SPR;
479 model_ptr->busy_tail->next = busy;
480 model_ptr->busy_tail = busy;
481 model_ptr->busy[unit] = 1;
482 model_ptr->nr_units[unit]++;
485 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
486 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
487 ppc_function_unit first_unit = time_ptr->first_unit;
488 ppc_function_unit second_unit = time_ptr->second_unit;
489 int stall_increment = 0;
492 if (!model_ptr->busy[first_unit])
493 return model_make_busy(model_ptr, first_unit,
494 model_ptr->timing[index].issue,
495 model_ptr->timing[index].done);
497 if (!model_ptr->busy[second_unit])
498 return model_make_busy(model_ptr, second_unit,
499 model_ptr->timing[index].issue,
500 model_ptr->timing[index].done);
502 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
503 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
505 model_new_cycle(model_ptr);
508 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
509 void::model-function::model_serialize:itable_index index, model_data *model_ptr
510 while (model_ptr->busy_head.next) {
511 TRACE(trace_model,("waiting for pipeline to empty\n"));
512 model_ptr->nr_stalls_serialize++;
513 model_new_cycle(model_ptr);
515 (void) model_make_busy(model_ptr,
516 model_ptr->timing[index].first_unit,
517 model_ptr->timing[index].issue,
518 model_ptr->timing[index].done);
520 # Wait for a CR to become unbusy
521 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
525 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
528 cr_mask = (1 << cr_var);
529 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
530 TRACE(trace_model,("waiting for CR %d\n", cr_var));
531 model_ptr->nr_stalls_data++;
532 model_new_cycle(model_ptr);
535 # Schedule an instruction that takes integer input registers and produces output registers
536 void::model-function::ppc_insn_int:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask
537 const uint32_t int_mask = out_mask | in_mask;
538 model_busy *busy_ptr;
540 if ((model_ptr->int_busy & int_mask) != 0) {
541 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
543 while ((model_ptr->int_busy & int_mask) != 0) {
544 if (WITH_TRACE && ppc_trace[trace_model])
545 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
547 model_ptr->nr_stalls_data++;
548 model_new_cycle(model_ptr);
552 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
553 model_ptr->int_busy |= out_mask;
554 busy_ptr->int_busy |= out_mask;
556 busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
558 if (WITH_TRACE && ppc_trace[trace_model])
559 model_trace_make_busy(model_ptr, out_mask, 0, 0);
561 # Schedule an instruction that takes integer input registers and produces output registers & sets a CR register
562 void::model-function::ppc_insn_int_cr:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask, const uint32_t cr_mask
563 const uint32_t int_mask = out_mask | in_mask;
564 model_busy *busy_ptr;
566 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
567 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
569 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
570 if (WITH_TRACE && ppc_trace[trace_model])
571 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
573 model_ptr->nr_stalls_data++;
574 model_new_cycle(model_ptr);
578 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
579 model_ptr->int_busy |= out_mask;
580 busy_ptr->int_busy |= out_mask;
581 model_ptr->cr_fpscr_busy |= cr_mask;
582 busy_ptr->cr_fpscr_busy |= cr_mask;
584 busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2;
587 busy_ptr->nr_writebacks++;
589 if (WITH_TRACE && ppc_trace[trace_model])
590 model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
593 # Schedule an instruction that takes CR input registers and produces output CR registers
594 void::model-function::ppc_insn_cr:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask
595 const uint32_t cr_mask = out_mask | in_mask;
596 model_busy *busy_ptr;
598 if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
599 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
601 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
602 if (WITH_TRACE && ppc_trace[trace_model])
603 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
605 model_ptr->nr_stalls_data++;
606 model_new_cycle(model_ptr);
610 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
611 model_ptr->cr_fpscr_busy |= out_mask;
612 busy_ptr->cr_fpscr_busy |= out_mask;
614 busy_ptr->nr_writebacks = 1;
616 if (WITH_TRACE && ppc_trace[trace_model])
617 model_trace_make_busy(model_ptr, 0, 0, out_mask);
620 # Schedule an instruction that takes floating point input registers and produces an output fp register
621 void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask
622 const uint32_t fp_mask = out_mask | in_mask;
623 model_busy *busy_ptr;
625 if ((model_ptr->fp_busy & fp_mask) != 0) {
626 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
628 while ((model_ptr->fp_busy & fp_mask) != 0) {
629 if (WITH_TRACE && ppc_trace[trace_model])
630 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
632 model_ptr->nr_stalls_data++;
633 model_new_cycle(model_ptr);
637 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
638 model_ptr->fp_busy |= out_mask;
639 busy_ptr->fp_busy |= out_mask;
640 busy_ptr->nr_writebacks = 1;
641 if (WITH_TRACE && ppc_trace[trace_model])
642 model_trace_make_busy(model_ptr, 0, out_mask, 0);
645 # Schedule an instruction that takes floating point input registers and produces an output fp register & sets a CR reg
646 void::model-function::ppc_insn_float_cr:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask, const uint32_t cr_mask
647 const uint32_t fp_mask = out_mask | in_mask;
648 model_busy *busy_ptr;
650 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
651 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
653 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
654 if (WITH_TRACE && ppc_trace[trace_model])
655 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
657 model_ptr->nr_stalls_data++;
658 model_new_cycle(model_ptr);
662 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
663 model_ptr->fp_busy |= out_mask;
664 busy_ptr->fp_busy |= out_mask;
665 model_ptr->cr_fpscr_busy |= cr_mask;
666 busy_ptr->cr_fpscr_busy |= cr_mask;
667 busy_ptr->nr_writebacks = (cr_mask) ? 2 : 1;
668 if (WITH_TRACE && ppc_trace[trace_model])
669 model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
672 # Schedule an instruction that takes both int/float input registers and produces output int/float registers
673 void::model-function::ppc_insn_int_float:itable_index index, model_data *model_ptr, const uint32_t out_int_mask, const uint32_t out_fp_mask, const uint32_t in_int_mask, const uint32_t in_fp_mask
674 const uint32_t int_mask = out_int_mask | in_int_mask;
675 const uint32_t fp_mask = out_fp_mask | in_fp_mask;
676 model_busy *busy_ptr;
678 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
679 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
681 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
682 if (WITH_TRACE && ppc_trace[trace_model])
683 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
685 model_ptr->nr_stalls_data++;
686 model_new_cycle(model_ptr);
689 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
690 model_ptr->int_busy |= out_int_mask;
691 busy_ptr->int_busy |= out_int_mask;
692 model_ptr->fp_busy |= out_fp_mask;
693 busy_ptr->fp_busy |= out_fp_mask;
694 busy_ptr->nr_writebacks = ((out_int_mask) ? 1 : 0) + ((out_fp_mask) ? 1 : 0);
695 if (WITH_TRACE && ppc_trace[trace_model])
696 model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0);
700 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
701 void::model-function::ppc_insn_from_spr:itable_index index, model_data *model_ptr, const uint32_t int_mask, const unsigned nSPR
702 model_busy *busy_ptr;
704 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
705 if (WITH_TRACE && ppc_trace[trace_model])
706 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
708 model_ptr->nr_stalls_data++;
709 model_new_cycle(model_ptr);
712 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
713 model_ptr->int_busy |= int_mask;
714 busy_ptr->int_busy |= int_mask;
715 busy_ptr->nr_writebacks = 1;
716 if (WITH_TRACE && ppc_trace[trace_model])
717 model_trace_make_busy(model_ptr, int_mask, 0, 0);
719 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
720 void::model-function::ppc_insn_to_spr:itable_index index, model_data *model_ptr, const uint32_t int_mask, const unsigned nSPR
721 model_busy *busy_ptr;
723 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
724 if (WITH_TRACE && ppc_trace[trace_model])
725 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
727 model_ptr->nr_stalls_data++;
728 model_new_cycle(model_ptr);
731 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
732 busy_ptr->spr_busy = nSPR;
733 model_ptr->spr_busy[nSPR] = 1;
734 busy_ptr->nr_writebacks = 1;
735 TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));
737 # Schedule a MFCR instruction that moves the CR into an integer register
738 void::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, uint32_t int_mask
739 const uint32_t cr_mask = 0xff;
740 model_busy *busy_ptr;
742 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
743 if (WITH_TRACE && ppc_trace[trace_model])
744 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
746 model_ptr->nr_stalls_data++;
747 model_new_cycle(model_ptr);
750 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
751 model_ptr->int_busy |= int_mask;
752 busy_ptr->int_busy |= int_mask;
753 busy_ptr->nr_writebacks = 1;
754 if (WITH_TRACE && ppc_trace[trace_model])
755 model_trace_make_busy(model_ptr, int_mask, 0, 0);
757 # Schedule a MTCR instruction that moves an integer register into the CR
758 void::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, uint32_t int_mask, unsigned FXM
761 uint32_t cr_mask = 0;
762 const model_time *normal_time = &model_ptr->timing[index];
763 static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 };
764 model_busy *busy_ptr;
766 for (f = 0; f < 8; f++) {
767 if (FXM & (0x80 >> f)) {
773 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
774 if (WITH_TRACE && ppc_trace[trace_model])
775 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
777 model_ptr->nr_stalls_data++;
778 model_new_cycle(model_ptr);
781 /* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */
782 if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) {
783 normal_time = &ppc604_1bit_time;
786 busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
787 busy_ptr->cr_fpscr_busy |= cr_mask;
788 model_ptr->cr_fpscr_busy |= cr_mask;
789 model_ptr->nr_mtcrf_crs[nr_crs]++;
790 busy_ptr->nr_writebacks = 1;
791 if (WITH_TRACE && ppc_trace[trace_model])
792 model_trace_make_busy(model_ptr, 0, 0, cr_mask);
794 model_data *::model-function::model_create:cpu *processor
795 model_data *model_ptr = ZALLOC(model_data);
796 model_ptr->name = model_name[CURRENT_MODEL];
797 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
798 model_ptr->processor = processor;
799 model_ptr->nr_cycles = 1;
800 model_ptr->busy_tail = &model_ptr->busy_head;
801 switch (CURRENT_MODEL) {
802 case MODEL_ppc601: model_ptr->max_nr_writebacks = 1; break; /* ??? */
803 case MODEL_ppc603: model_ptr->max_nr_writebacks = 2; break;
804 case MODEL_ppc603e: model_ptr->max_nr_writebacks = 2; break;
805 case MODEL_ppc604: model_ptr->max_nr_writebacks = 2; break;
806 default: error ("Unknown model %d\n", CURRENT_MODEL);
810 void::model-function::model_init:model_data *model_ptr
812 void::model-function::model_halt:model_data *model_ptr
813 /* Let pipeline drain */
814 while (model_ptr->busy_head.next)
815 model_new_cycle(model_ptr);
817 unsigned_word::model-function::model_get_number_of_stalls:model_data *model_ptr
818 return (model_ptr->nr_stalls_data
819 + model_ptr->nr_stalls_unit
820 + model_ptr->nr_stalls_serialize
821 + model_ptr->nr_stalls_writeback);
823 unsigned_word::model-function::model_get_number_of_cycles:model_data *model_ptr
824 return (model_ptr->nr_cycles);
826 model_print *::model-function::model_mon_info:model_data *model_ptr
833 head = tail = ZALLOC(model_print);
834 tail->count = model_ptr->nr_cycles;
835 tail->name = "cycle";
836 tail->suffix_plural = "s";
837 tail->suffix_singular = "";
839 if (model_ptr->nr_stalls_data) {
840 tail->next = ZALLOC(model_print);
842 tail->count = model_ptr->nr_stalls_data;
843 tail->name = "stall";
844 tail->suffix_plural = "s waiting for data";
845 tail->suffix_singular = " waiting for data";
848 if (model_ptr->nr_stalls_unit) {
849 tail->next = ZALLOC(model_print);
851 tail->count = model_ptr->nr_stalls_unit;
852 tail->name = "stall";
853 tail->suffix_plural = "s waiting for a function unit";
854 tail->suffix_singular = " waiting for a function unit";
857 if (model_ptr->nr_stalls_serialize) {
858 tail->next = ZALLOC(model_print);
860 tail->count = model_ptr->nr_stalls_serialize;
861 tail->name = "stall";
862 tail->suffix_plural = "s waiting for serialization";
863 tail->suffix_singular = " waiting for serialization";
866 if (model_ptr->nr_stalls_writeback) {
867 tail->next = ZALLOC(model_print);
869 tail->count = model_ptr->nr_stalls_writeback;
871 tail->suffix_plural = "times a write-back slot was unavailable";
872 tail->suffix_singular = "time a writeback was unavailable";
875 if (model_ptr->nr_branches) {
876 tail->next = ZALLOC(model_print);
878 tail->count = model_ptr->nr_branches;
879 tail->name = "branch";
880 tail->suffix_plural = "es";
881 tail->suffix_singular = "";
884 if (model_ptr->nr_branches_fallthrough) {
885 tail->next = ZALLOC(model_print);
887 tail->count = model_ptr->nr_branches_fallthrough;
888 tail->name = "conditional branch";
889 tail->suffix_plural = "es fell through";
890 tail->suffix_singular = " fell through";
893 if (model_ptr->nr_branch_predict_trues) {
894 tail->next = ZALLOC(model_print);
896 tail->count = model_ptr->nr_branch_predict_trues;
897 tail->name = "successful branch prediction";
898 tail->suffix_plural = "s";
899 tail->suffix_singular = "";
902 if (model_ptr->nr_branch_predict_falses) {
903 tail->next = ZALLOC(model_print);
905 tail->count = model_ptr->nr_branch_predict_falses;
906 tail->name = "unsuccessful branch prediction";
907 tail->suffix_plural = "s";
908 tail->suffix_singular = "";
911 for (j = 0; j < ARRAY_SIZE (ppc_branch_conditional_name); j++) {
912 if (model_ptr->nr_branch_conditional[j]) {
913 tail->next = ZALLOC(model_print);
915 tail->count = model_ptr->nr_branch_conditional[j];
916 tail->name = ppc_branch_conditional_name[j];
917 tail->suffix_plural = " conditional branches";
918 tail->suffix_singular = " conditional branch";
922 for (j = 0; j < 9; j++) {
923 if (model_ptr->nr_mtcrf_crs[j]) {
924 tail->next = ZALLOC(model_print);
926 tail->count = model_ptr->nr_mtcrf_crs[j];
927 tail->name = ppc_nr_mtcrf_crs[j];
928 tail->suffix_plural = " instructions";
929 tail->suffix_singular = " instruction";
934 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
935 if (model_ptr->nr_units[i]) {
936 nr_insns += model_ptr->nr_units[i];
937 tail->next = ZALLOC(model_print);
939 tail->count = model_ptr->nr_units[i];
940 tail->name = ppc_function_unit_name[i];
941 tail->suffix_plural = "s";
942 tail->suffix_singular = "";
946 tail->next = ZALLOC(model_print);
948 tail->count = nr_insns;
949 tail->name = "instruction";
950 tail->suffix_plural = "s that were accounted for in timing info";
951 tail->suffix_singular = " that was accounted for in timing info";
953 tail->next = (model_print *)0;
956 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
958 model_print *next = ptr->next;
963 void::model-function::model_branches:model_data *model_ptr, int failed, int conditional
964 model_ptr->nr_units[PPC_UNIT_BPU]++;
966 model_ptr->nr_branches_fallthrough++;
968 model_ptr->nr_branches++;
969 if (conditional >= 0)
970 model_ptr->nr_branch_conditional[conditional]++;
971 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
973 void::model-function::model_branch_predict:model_data *model_ptr, int success
975 model_ptr->nr_branch_predict_trues++;
977 model_ptr->nr_branch_predict_falses++;
980 # The following (illegal) instruction is `known' by gen and is
981 # called when ever an illegal instruction is encountered
983 program_interrupt(processor, cia,
984 illegal_instruction_program_interrupt);
987 # The following (floating point unavailable) instruction is `known' by gen
988 # and is called when ever an a floating point instruction is to be
989 # executed but floating point is make unavailable by the MSR
990 ::internal::floating_point_unavailable
991 floating_point_unavailable_interrupt(processor, cia);
995 # Floating point support functions
998 # Convert 32bit single to 64bit double
999 uint64_t::function::DOUBLE:uint32_t WORD
1001 if (EXTRACTED32(WORD, 1, 8) > 0
1002 && EXTRACTED32(WORD, 1, 8) < 255) {
1003 /* normalized operand */
1004 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
1005 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
1006 | INSERTED64(not_word_1_1, 2, 2)
1007 | INSERTED64(not_word_1_1, 3, 3)
1008 | INSERTED64(not_word_1_1, 4, 4)
1009 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
1011 else if (EXTRACTED32(WORD, 1, 8) == 0
1012 && EXTRACTED32(WORD, 9, 31) != 0) {
1013 /* denormalized operand */
1014 int sign = EXTRACTED32(WORD, 0, 0);
1016 uint64_t frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
1017 /* normalize the operand */
1018 while (MASKED64(frac, 0, 0) == 0) {
1022 FRT = (INSERTED64(sign, 0, 0)
1023 | INSERTED64(exp + 1023, 1, 11)
1024 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
1026 else if (EXTRACTED32(WORD, 1, 8) == 255
1027 || EXTRACTED32(WORD, 1, 31) == 0) {
1028 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
1029 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
1030 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
1031 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
1032 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
1035 error("DOUBLE - unknown case\n");
1040 # Convert 64bit single to 32bit double
1041 uint32_t::function::SINGLE:uint64_t FRS
1043 if (EXTRACTED64(FRS, 1, 11) > 896
1044 || EXTRACTED64(FRS, 1, 63) == 0) {
1045 /* no denormalization required (includes Zero/Infinity/NaN) */
1046 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
1047 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
1049 else if (874 <= EXTRACTED64(FRS, 1, 11)
1050 && EXTRACTED64(FRS, 1, 11) <= 896) {
1051 /* denormalization required */
1052 int sign = EXTRACTED64(FRS, 0, 0);
1053 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
1054 uint64_t frac = (BIT64(0)
1055 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
1056 /* denormalize the operand */
1057 while (exp < -126) {
1058 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1061 WORD = (INSERTED32(sign, 0, 0)
1062 | INSERTED32(0x00, 1, 8)
1063 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
1066 WORD = 0x0; /* ??? */
1071 # round 64bit double to 64bit but single
1072 void::function::Round_Single:cpu *processor, int sign, int *exp, uint64_t *frac_grx
1073 /* comparisons ignore u bits */
1076 int lsb = EXTRACTED64(*frac_grx, 23, 23);
1077 int gbit = EXTRACTED64(*frac_grx, 24, 24);
1078 int rbit = EXTRACTED64(*frac_grx, 25, 25);
1079 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
1080 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
1081 if (lsb == 1 && gbit == 1) inc = 1;
1082 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1083 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1085 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
1086 if (sign == 0 && gbit == 1) inc = 1;
1087 if (sign == 0 && rbit == 1) inc = 1;
1088 if (sign == 0 && xbit == 1) inc = 1;
1090 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
1091 if (sign == 1 && gbit == 1) inc = 1;
1092 if (sign == 1 && rbit == 1) inc = 1;
1093 if (sign == 1 && xbit == 1) inc = 1;
1095 /* work out addition in low 25 bits of out */
1096 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
1097 *frac_grx = INSERTED64(out, 0, 23);
1098 if (out & BIT64(64 - 23 - 1 - 1)) {
1099 *frac_grx = (BIT64(0) |
1100 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
1103 /* frac_grx[24:52] = 0 already */
1105 FPSCR_SET_FI(gbit || rbit || xbit);
1109 void::function::Round_Integer:cpu *processor, int sign, uint64_t *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
1111 if (round_mode == fpscr_rn_round_to_nearest) {
1112 if (*frac64 == 1 && gbit == 1) inc = 1;
1113 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
1114 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
1116 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1117 if (sign == 0 && gbit == 1) inc = 1;
1118 if (sign == 0 && rbit == 1) inc = 1;
1119 if (sign == 0 && xbit == 1) inc = 1;
1121 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1122 if (sign == 1 && gbit == 1) inc = 1;
1123 if (sign == 1 && rbit == 1) inc = 1;
1124 if (sign == 1 && xbit == 1) inc = 1;
1126 /* frac[0:64] = frac[0:64} + inc */
1127 *frac += (*frac64 && inc ? 1 : 0);
1128 *frac64 = (*frac64 + inc) & 0x1;
1130 FPSCR_SET_FI(gbit | rbit | xbit);
1133 void::function::Round_Float:cpu *processor, int sign, int *exp, uint64_t *frac, fpscreg round_mode
1136 int lsb = EXTRACTED64(*frac, 52, 52);
1137 int gbit = EXTRACTED64(*frac, 53, 53);
1138 int rbit = EXTRACTED64(*frac, 54, 54);
1139 int xbit = EXTRACTED64(*frac, 55, 55);
1140 if (round_mode == fpscr_rn_round_to_nearest) {
1141 if (lsb == 1 && gbit == 1) inc = 1;
1142 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1143 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1145 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1146 if (sign == 0 && gbit == 1) inc = 1;
1147 if (sign == 0 && rbit == 1) inc = 1;
1148 if (sign == 0 && xbit == 1) inc = 1;
1150 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1151 if (sign == 1 && gbit == 1) inc = 1;
1152 if (sign == 1 && rbit == 1) inc = 1;
1153 if (sign == 1 && xbit == 1) inc = 1;
1155 /* frac//carry_out = frac + inc */
1156 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1157 carry_out = EXTRACTED64(*frac, 0, 0);
1159 if (carry_out == 1) *exp = *exp + 1;
1161 FPSCR_SET_FI(gbit | rbit | xbit);
1162 FPSCR_SET_XX(FPSCR & fpscr_fi);
1165 # conversion of FP to integer
1166 void::function::convert_to_integer:cpu *processor, unsigned_word cia, uint64_t *frt, uint64_t frb, fpscreg round_mode, int tgt_precision
1174 int sign = EXTRACTED64(frb, 0, 0);
1176 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1177 GOTO(Infinity_Operand);
1178 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1180 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1182 if (EXTRACTED64(frb, 1, 11) > 1086) GOTO(Large_Operand);
1183 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1184 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1185 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1186 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1189 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1190 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1193 gbit = 0, rbit = 0, xbit = 0;
1194 for (i = 1; i <= 63 - exp; i++) {
1198 frac64 = EXTRACTED64(frac, 63, 63);
1199 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1201 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1202 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1205 frac += (frac64 ? 1 : 0);
1206 frac64 = (frac64 + 1) & 0x1;
1208 if (tgt_precision == 32 /* can ignore frac64 in compare */
1209 && (int64_t)frac > (int64_t)MASK64(33+1, 63)/*2^31-1 >>1*/)
1210 GOTO(Large_Operand);
1211 if (tgt_precision == 64 /* can ignore frac64 in compare */
1212 && (int64_t)frac > (int64_t)MASK64(1+1, 63)/*2^63-1 >>1*/)
1213 GOTO(Large_Operand);
1214 if (tgt_precision == 32 /* can ignore frac64 in compare */
1215 && (int64_t)frac < (int64_t)MASK64(0, 32+1)/*-2^31 >>1*/)
1216 GOTO(Large_Operand);
1217 if (tgt_precision == 64 /* can ignore frac64 in compare */
1218 && (int64_t)frac < (int64_t)MASK64(0, 0+1)/*-2^63 >>1*/)
1219 GOTO(Large_Operand);
1220 FPSCR_SET_XX(FPSCR & fpscr_fi);
1221 if (tgt_precision == 32)
1222 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1223 if (tgt_precision == 64)
1224 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1225 /*FPSCR[fprf] = undefined */
1228 LABEL(Infinity_Operand):
1231 FPSCR_OR_VX(fpscr_vxcvi);
1232 if ((FPSCR & fpscr_ve) == 0) {
1233 if (tgt_precision == 32) {
1234 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1235 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1238 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1239 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1241 /* FPSCR[FPRF] = undefined */
1245 LABEL(SNaN_Operand):
1248 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1249 if ((FPSCR & fpscr_ve) == 0) {
1250 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1251 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1252 /* FPSCR[fprf] = undefined */
1256 LABEL(QNaN_Operand):
1259 FPSCR_OR_VX(fpscr_vxcvi);
1260 if ((FPSCR & fpscr_ve) == 0) {
1261 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1262 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1263 /* FPSCR[fprf] = undefined */
1267 LABEL(Large_Operand):
1270 FPSCR_OR_VX(fpscr_vxcvi);
1271 if ((FPSCR & fpscr_ve) == 0) {
1272 if (tgt_precision == 32) {
1273 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1274 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1277 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1278 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1280 /* FPSCR[fprf] = undefined */
1286 # extract out raw fields of a FP number
1287 int::function::sign:uint64_t FRS
1288 return (MASKED64(FRS, 0, 0)
1291 int::function::biased_exp:uint64_t frs, int single
1293 return EXTRACTED64(frs, 1, 8);
1295 return EXTRACTED64(frs, 1, 11);
1296 uint64_t::function::fraction:uint64_t frs, int single
1298 return EXTRACTED64(frs, 9, 31);
1300 return EXTRACTED64(frs, 12, 63);
1302 # a number?, each of the below return +1 or -1 (based on sign bit)
1304 int::function::is_nor:uint64_t frs, int single
1305 int exp = biased_exp(frs, single);
1307 && exp <= (single ? 254 : 2046));
1308 int::function::is_zero:uint64_t FRS
1309 return (MASKED64(FRS, 1, 63) == 0
1312 int::function::is_den:uint64_t frs, int single
1313 int exp = biased_exp(frs, single);
1314 uint64_t frac = fraction(frs, single);
1315 return (exp == 0 && frac != 0
1318 int::function::is_inf:uint64_t frs, int single
1319 int exp = biased_exp(frs, single);
1320 uint64_t frac = fraction(frs, single);
1321 return (exp == (single ? 255 : 2047) && frac == 0
1324 int::function::is_NaN:uint64_t frs, int single
1325 int exp = biased_exp(frs, single);
1326 uint64_t frac = fraction(frs, single);
1327 return (exp == (single ? 255 : 2047) && frac != 0
1330 int::function::is_SNaN:uint64_t frs, int single
1331 return (is_NaN(frs, single)
1332 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1335 int::function::is_QNaN:uint64_t frs, int single
1336 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1337 int::function::is_less_than:uint64_t *fra, uint64_t *frb
1338 return *(double*)fra < *(double*)frb;
1339 int::function::is_greater_than:uint64_t *fra, uint64_t *frb
1340 return *(double*)fra > *(double*)frb;
1341 int::function::is_equan_to:uint64_t *fra, uint64_t *frb
1342 return *(double*)fra == *(double*)frb;
1345 # which quiet nan should become the result
1346 uint64_t::function::select_qnan:uint64_t fra, uint64_t frb, uint64_t frc, int instruction_is_frsp, int generate_qnan, int single
1348 if (is_NaN(fra, single))
1350 else if (is_NaN(frb, single))
1351 if (instruction_is_frsp)
1352 frt = MASKED64(frb, 0, 34);
1355 else if (is_NaN(frc, single))
1357 else if (generate_qnan)
1358 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1360 error("select_qnan - default reached\n");
1364 # detect invalid operation
1365 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, uint64_t fra, uint64_t frb, fpscreg check, int single, int negate
1367 if ((check & fpscr_vxsnan)
1368 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1369 FPSCR_OR_VX(fpscr_vxsnan);
1372 if ((check & fpscr_vxisi)
1373 && (is_inf(fra, single) && is_inf(frb, single))
1374 && ((negate && sign(fra) != sign(frb))
1375 || (!negate && sign(fra) == sign(frb)))) {
1376 /*FIXME: don't handle inf-inf VS inf+-inf */
1377 FPSCR_OR_VX(fpscr_vxisi);
1380 if ((check & fpscr_vxidi)
1381 && (is_inf(fra, single) && is_inf(frb, single))) {
1382 FPSCR_OR_VX(fpscr_vxidi);
1385 if ((check & fpscr_vxzdz)
1386 && (is_zero(fra) && is_zero(frb))) {
1387 FPSCR_OR_VX(fpscr_vxzdz);
1390 if ((check & fpscr_vximz)
1391 && (is_zero(fra) && is_inf(frb, single))) {
1392 FPSCR_OR_VX(fpscr_vximz);
1395 if ((check & fpscr_vxvc)
1396 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1397 FPSCR_OR_VX(fpscr_vxvc);
1400 if ((check & fpscr_vxsoft)) {
1401 FPSCR_OR_VX(fpscr_vxsoft);
1404 if ((check & fpscr_vxsqrt)
1406 FPSCR_OR_VX(fpscr_vxsqrt);
1409 /* if ((check && fpscr_vxcvi) {
1410 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1411 FPSCR_OR_VX(fpscr_vxcvi);
1421 # handle case of invalid operation
1422 void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, uint64_t *frt, uint64_t fra, uint64_t frb, uint64_t frc, int instruction_is_frsp, int instruction_is_convert_to_64bit, int instruction_is_convert_to_32bit, int single
1423 if (FPSCR & fpscr_ve) {
1424 /* invalid operation exception enabled */
1428 /* fpscr_FPRF unchanged */
1431 /* invalid operation exception disabled */
1432 if (instruction_is_convert_to_64bit) {
1435 else if (instruction_is_convert_to_32bit) {
1438 else { /* arrith, frsp */
1439 *frt = select_qnan(fra, frb, frc,
1440 instruction_is_frsp, 1/*generate*/, single);
1443 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1450 # detect divide by zero
1451 int::function::is_invalid_zero_divide:cpu *processor, unsigned_word cia, uint64_t fra, uint64_t frb, int single
1453 if (is_zero (frb)) {
1462 # handle case of invalid operation
1463 void::function::invalid_zero_divide_operation:cpu *processor, unsigned_word cia, uint64_t *frt, uint64_t fra, uint64_t frb, int single
1464 if (FPSCR & fpscr_ze) {
1465 /* zero-divide exception enabled */
1469 /* fpscr_FPRF unchanged */
1472 /* zero-divide exception disabled */
1475 if ((sign (fra) < 0 && sign (frb) < 0)
1476 || (sign (fra) > 0 && sign (frb) > 0)) {
1477 *frt = MASK64 (1, 11); /* 0 : 2047 : 0..0 */
1478 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
1481 *frt = MASK64 (0, 11); /* 1 : 2047 : 0..0 */
1482 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
1491 # 0.0.0.0 Illegal instruction used for kernel mode emulation
1493 0.0,6./,11./,16./,21./,31.1:X:::instruction_call
1494 if (!os_emul_instruction_call(processor, cia, real_addr(cia, 1)))
1495 program_interrupt(processor, cia,
1496 illegal_instruction_program_interrupt);
1499 # I.2.4.1 Branch Instructions
1501 0.18,6.LI,30.AA,31.LK:I:::Branch
1502 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1503 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1504 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1505 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1507 No problem here because this branch is predicted taken (unconditional). */
1508 if (AA) NIA = IEA(EXTS(LI_0b00));
1509 else NIA = IEA(CIA + EXTS(LI_0b00));
1510 if (LK) LR = (spreg)CIA+4;
1511 if (CURRENT_MODEL_ISSUE > 0)
1512 model_branches(cpu_model(processor), 1, -1);
1514 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:::Branch Conditional
1515 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1516 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1517 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1518 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1519 int M, ctr_ok, cond_ok, succeed;
1520 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1521 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1522 if (is_64bit_implementation && is_64bit_mode) M = 0;
1524 if (!BO{2}) CTR = CTR - 1;
1525 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1526 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1527 if (ctr_ok && cond_ok) {
1528 if (AA) NIA = IEA(EXTS(BD_0b00));
1529 else NIA = IEA(CIA + EXTS(BD_0b00));
1534 if (LK) LR = (spreg)IEA(CIA + 4);
1535 if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
1536 /* This branch is predicted as "normal".
1537 If this is a forward branch and it is near the end of a page,
1538 we've detected a problematic branch. */
1539 if (succeed && NIA > CIA) {
1540 if (MPC860C0_PAGE_SIZE - (CIA & (MPC860C0_PAGE_SIZE-1)) <= option_mpc860c0)
1541 program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt);
1544 if (CURRENT_MODEL_ISSUE > 0)
1545 model_branches(cpu_model(processor), succeed, BO);
1548 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1549 reverse = EXTS(BD_0b00) < 0;
1550 } else { /* branch prediction bit not set */
1551 reverse = EXTS(BD_0b00) >= 0;
1553 if (CURRENT_MODEL_ISSUE > 0)
1554 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1557 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:::Branch Conditional to Link Register
1558 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1559 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1560 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1561 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1562 int M, ctr_ok, cond_ok, succeed;
1563 if (is_64bit_implementation && is_64bit_mode) M = 0;
1565 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1566 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1567 if (!BO{2}) CTR = CTR - 1;
1568 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1569 cond_ok = BO{0} || (CR{BI} == BO{1});
1570 if (ctr_ok && cond_ok) {
1576 if (LK) LR = (spreg)IEA(CIA + 4);
1577 if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
1578 /* This branch is predicted as not-taken.
1579 If this is a forward branch and it is near the end of a page,
1580 we've detected a problematic branch. */
1581 if (succeed && NIA > CIA) {
1582 if (MPC860C0_PAGE_SIZE - (CIA & (MPC860C0_PAGE_SIZE-1)) <= option_mpc860c0)
1583 program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt);
1586 if (CURRENT_MODEL_ISSUE > 0) {
1587 model_branches(cpu_model(processor), succeed, BO);
1589 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1592 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:::Branch Conditional to Count Register
1593 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1594 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1595 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1596 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1597 int cond_ok, succeed;
1598 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1599 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1600 cond_ok = BO{0} || (CR{BI} == BO{1});
1602 NIA = IEA(CTR_0b00);
1607 if (LK) LR = (spreg)IEA(CIA + 4);
1608 if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
1609 /* This branch is predicted as not-taken.
1610 If this is a forward branch and it is near the end of a page,
1611 we've detected a problematic branch. */
1612 if (succeed && NIA > CIA) {
1613 if (MPC860C0_PAGE_SIZE - (CIA & (MPC860C0_PAGE_SIZE-1)) <= option_mpc860c0)
1614 program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt);
1617 if (CURRENT_MODEL_ISSUE > 0) {
1618 model_branches(cpu_model(processor), succeed, BO);
1620 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1624 # I.2.4.2 System Call Instruction
1626 0.17,6./,11./,16./,30.1,31./:SC:::System Call
1627 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1628 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1629 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1630 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1631 if (CURRENT_MODEL_ISSUE > 0)
1632 model_serialize(MY_INDEX, cpu_model(processor));
1633 system_call_interrupt(processor, cia);
1636 # I.2.4.3 Condition Register Logical Instructions
1638 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1639 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1640 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1641 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1642 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1643 BLIT32(CR, BT, CR{BA} && CR{BB});
1644 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1646 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1647 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1648 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1649 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1650 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1651 BLIT32(CR, BT, CR{BA} || CR{BB});
1652 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1654 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1655 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1656 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1657 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1658 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1659 BLIT32(CR, BT, CR{BA} != CR{BB});
1660 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1662 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1663 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1664 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1665 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1666 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1667 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1668 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1670 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1671 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1672 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1673 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1674 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1675 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1676 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1678 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1679 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1680 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1681 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1682 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1683 BLIT32(CR, BT, CR{BA} == CR{BB});
1684 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1686 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1687 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1688 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1689 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1690 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1691 BLIT32(CR, BT, CR{BA} && !CR{BB});
1692 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1694 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1695 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1696 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1697 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1698 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1699 BLIT32(CR, BT, CR{BA} || !CR{BB});
1700 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1703 # I.2.4.4 Condition Register Field Instruction
1705 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1706 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1707 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1708 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1709 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1710 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1711 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
1715 # I.3.3.2 Fixed-Point Load Instructions
1718 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1719 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1720 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1721 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1722 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1728 *rT = MEM(unsigned, EA, 1);
1729 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1732 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1733 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1734 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1735 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1736 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1742 *rT = MEM(unsigned, EA, 1);
1743 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1745 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1746 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1747 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1748 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1749 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1751 if (RA_is_0 || RA == RT)
1752 program_interrupt(processor, cia,
1753 illegal_instruction_program_interrupt);
1755 *rT = MEM(unsigned, EA, 1);
1757 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1759 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1760 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1761 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1762 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1763 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1765 if (RA_is_0 || RA == RT)
1766 program_interrupt(processor, cia,
1767 illegal_instruction_program_interrupt);
1769 *rT = MEM(unsigned, EA, 1);
1771 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1773 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1774 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1775 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1776 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1777 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1783 *rT = MEM(unsigned, EA, 2);
1784 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1786 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1787 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1788 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1789 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1790 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1796 *rT = MEM(unsigned, EA, 2);
1797 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1799 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1800 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1801 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1802 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1803 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1805 if (RA_is_0 || RA == RT)
1806 program_interrupt(processor, cia,
1807 illegal_instruction_program_interrupt);
1809 *rT = MEM(unsigned, EA, 2);
1811 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1813 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1814 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1815 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1816 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1817 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1819 if (RA_is_0 || RA == RT)
1820 program_interrupt(processor, cia,
1821 illegal_instruction_program_interrupt);
1823 *rT = MEM(unsigned, EA, 2);
1825 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1827 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1828 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1829 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1830 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1831 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1837 *rT = MEM(signed, EA, 2);
1838 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1840 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1841 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1842 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1843 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1844 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1850 *rT = MEM(signed, EA, 2);
1851 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1853 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1854 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1855 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1856 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1857 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1859 if (RA_is_0 || RA == RT)
1860 program_interrupt(processor, cia,
1861 illegal_instruction_program_interrupt);
1863 *rT = MEM(signed, EA, 2);
1865 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1867 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1868 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1869 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1870 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1871 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1873 if (RA_is_0 || RA == RT)
1874 program_interrupt(processor, cia,
1875 illegal_instruction_program_interrupt);
1877 *rT = MEM(signed, EA, 2);
1879 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1881 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1882 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1883 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1884 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1885 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1891 *rT = MEM(unsigned, EA, 4);
1892 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1894 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1895 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1896 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1897 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1898 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1904 *rT = MEM(unsigned, EA, 4);
1905 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1907 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1908 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1909 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1910 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1911 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1913 if (RA_is_0 || RA == RT)
1914 program_interrupt(processor, cia,
1915 illegal_instruction_program_interrupt);
1917 *rT = MEM(unsigned, EA, 4);
1919 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1921 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1922 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1923 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1924 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1925 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1927 if (RA_is_0 || RA == RT)
1928 program_interrupt(processor, cia,
1929 illegal_instruction_program_interrupt);
1931 *rT = MEM(unsigned, EA, 4);
1933 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1935 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1938 # if (RA_is_0) b = 0;
1940 # EA = b + EXTS(DS_0b00);
1941 # *rT = MEM(signed, EA, 4);
1943 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1946 # if (RA_is_0) b = 0;
1949 # *rT = MEM(signed, EA, 4);
1951 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1953 # if (RA_is_0 || RA == RT)
1954 # program_interrupt(processor, cia
1955 # illegal_instruction_program_interrupt);
1957 # *rT = MEM(signed, EA, 4);
1960 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1963 # if (RA_is_0) b = 0;
1965 # EA = b + EXTS(DS_0b00);
1966 # *rT = MEM(unsigned, EA, 8);
1968 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1971 # if (RA_is_0) b = 0;
1974 # *rT = MEM(unsigned, EA, 8);
1976 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1978 # if (RA_is_0 || RA == RT)
1979 # program_interrupt(processor, cia
1980 # illegal_instruction_program_interrupt);
1981 # EA = *rA + EXTS(DS_0b00);
1982 # *rT = MEM(unsigned, EA, 8);
1985 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1987 # if (RA_is_0 || RA == RT)
1988 # program_interrupt(processor, cia
1989 # illegal_instruction_program_interrupt);
1991 # *rT = MEM(unsigned, EA, 8);
1997 # I.3.3.3 Fixed-Point Store Instructions
2000 0.38,6.RS,11.RA,16.D:D:::Store Byte
2001 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2002 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2003 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2004 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2011 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
2013 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
2014 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2015 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2016 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2017 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2024 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2026 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
2027 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2028 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2029 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2030 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2033 program_interrupt(processor, cia,
2034 illegal_instruction_program_interrupt);
2038 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2040 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
2041 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2042 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2043 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2044 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2047 program_interrupt(processor, cia,
2048 illegal_instruction_program_interrupt);
2052 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2054 0.44,6.RS,11.RA,16.D:D:::Store Half Word
2055 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2056 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2057 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2058 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2065 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
2067 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
2068 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2069 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2070 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2071 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2078 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2080 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
2081 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2082 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2083 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2084 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2087 program_interrupt(processor, cia,
2088 illegal_instruction_program_interrupt);
2092 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2094 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
2095 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2096 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2097 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2098 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2101 program_interrupt(processor, cia,
2102 illegal_instruction_program_interrupt);
2106 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2108 0.36,6.RS,11.RA,16.D:D:::Store Word
2109 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2110 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2111 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2112 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2119 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
2121 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
2122 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2123 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2124 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2125 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2132 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2134 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
2135 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2136 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2137 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2138 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2141 program_interrupt(processor, cia,
2142 illegal_instruction_program_interrupt);
2146 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2148 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
2149 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2150 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2151 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2152 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2155 program_interrupt(processor, cia,
2156 illegal_instruction_program_interrupt);
2160 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2162 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2165 # if (RA_is_0) b = 0;
2167 # EA = b + EXTS(DS_0b00);
2168 # STORE(EA, 8, *rS);
2169 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2172 # if (RA_is_0) b = 0;
2175 # STORE(EA, 8, *rS);
2176 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2179 # program_interrupt(processor, cia
2180 # illegal_instruction_program_interrupt);
2181 # EA = *rA + EXTS(DS_0b00);
2182 # STORE(EA, 8, *rS);
2184 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2187 # program_interrupt(processor, cia
2188 # illegal_instruction_program_interrupt);
2190 # STORE(EA, 8, *rS);
2195 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2198 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2199 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2200 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2201 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2202 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2208 *rT = SWAP_2(MEM(unsigned, EA, 2));
2209 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2211 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2212 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2213 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2214 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2215 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2221 *rT = SWAP_4(MEM(unsigned, EA, 4));
2222 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2224 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2225 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2226 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2227 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2228 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2234 STORE(EA, 2, SWAP_2(*rS));
2235 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2237 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2238 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2239 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2240 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2241 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2247 STORE(EA, 4, SWAP_4(*rS));
2248 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2252 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2255 0.46,6.RT,11.RA,16.D:D:::Load Multiple Word
2264 program_interrupt(processor, cia,
2265 illegal_instruction_program_interrupt);
2266 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT || (EA % 4 != 0))
2267 alignment_interrupt(processor, cia, EA);
2269 GPR(r) = MEM(unsigned, EA, 4);
2274 0.47,6.RS,11.RA,16.D:D:::Store Multiple Word
2281 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT
2283 alignment_interrupt(processor, cia, EA);
2286 STORE(EA, 4, GPR(r));
2293 # I.3.3.6 Fixed-Point Move Assist Instructions
2296 0.31,6.RT,11.RA,16.NB,21.597,31./:X:::Load String Word Immediate
2302 if (RA_is_0) EA = 0;
2304 if (NB == 0) n = 32;
2310 ? (RA >= RT || RA < (RT + nr) % 32)
2311 : (RA >= RT && RA < RT + nr))
2312 program_interrupt(processor, cia,
2313 illegal_instruction_program_interrupt);
2314 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2315 alignment_interrupt(processor, cia, EA);
2321 GPR(r) |= INSERTED(MEM(unsigned, EA, 1), i, i+7);
2323 if (i == 64) i = 32;
2328 0.31,6.RT,11.RA,16.RB,21.533,31./:X:::Load String Word Indexed
2338 n = EXTRACTED32(XER, 25, 31);
2342 if (((RT + nr >= 32)
2343 ? ((RA >= RT || RA < (RT + nr) % 32)
2344 || (RB >= RT || RB < (RT + nr) % 32))
2345 : ((RA >= RT && RA < RT + nr)
2346 || (RB >= RT && RB < RT + nr)))
2347 || (RT == RA || RT == RB))
2348 program_interrupt(processor, cia,
2349 illegal_instruction_program_interrupt);
2350 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2351 alignment_interrupt(processor, cia, EA);
2357 GPR(r) |= INSERTED(MEM(unsigned, EA, 1), i, i+7);
2359 if (i == 64) i = 32;
2364 0.31,6.RS,11.RA,16.NB,21.725,31./:X:::Store String Word Immedate
2369 if (RA_is_0) EA = 0;
2371 if (NB == 0) n = 32;
2375 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2376 alignment_interrupt(processor, cia, EA);
2378 if (i == 32) r = (r + 1) % 32;
2379 STORE(EA, 1, EXTRACTED(GPR(r), i, i+7));
2381 if (i == 64) i = 32;
2386 0.31,6.RS,11.RA,16.RB,21.661,31./:X:::Store String Word Indexed
2395 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2396 alignment_interrupt(processor, cia, EA);
2397 n = EXTRACTED32(XER, 25, 31);
2401 if (i == 32) r = (r + 1) % 32;
2402 STORE(EA, 1, EXTRACTED(GPR(r), i, i+7));
2404 if (i == 64) i = 32;
2411 # I.3.3.7 Storage Synchronization Instructions
2413 # HACK: Rather than monitor addresses looking for a reason
2414 # to cancel a reservation. This code instead keeps
2415 # a copy of the data read from memory. Before performing
2416 # a store, the memory area is checked to see if it has
2418 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2419 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2420 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2421 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2422 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2429 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2430 RESERVE_DATA = MEM(unsigned, EA, 4);
2432 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2434 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2441 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2442 RESERVE_DATA = MEM(unsigned, EA, 8);
2444 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2446 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2447 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2448 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2449 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2450 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2457 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2458 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2460 CR_SET_XER_SO(0, cr_i_zero);
2463 /* ment to randomly to store, we never do! */
2464 CR_SET_XER_SO(0, 0);
2469 CR_SET_XER_SO(0, 0);
2471 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2473 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2480 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2481 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2483 CR_SET_XER_SO(0, cr_i_zero);
2486 /* ment to randomly to store, we never do */
2487 CR_SET_XER_SO(0, 0);
2492 CR_SET_XER_SO(0, 0);
2494 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2496 0.31,6./,9.L,11./,16./,21.598,31./:X::sync:Synchronize
2497 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2498 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2499 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2500 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2505 # I.3.3.9 Fixed-Point Arithmetic Instructions
2508 0.14,6.RT,11.RA,16.SI:D:::Add Immediate
2509 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2510 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2511 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2512 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2513 if (RA_is_0) *rT = EXTS(SI);
2514 else *rT = *rA + EXTS(SI);
2515 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2516 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2518 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2519 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2520 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2521 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2522 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2523 if (RA_is_0) *rT = EXTS(SI) << 16;
2524 else *rT = *rA + (EXTS(SI) << 16);
2525 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2526 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2528 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2529 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2530 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2531 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2532 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2535 ALU_END(*rT, 0/*CA*/, OE, Rc);
2536 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2538 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2539 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2540 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2541 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2542 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2547 ALU_END(*rT, 0/*CA*/, OE, Rc);
2548 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2550 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2551 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2552 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2553 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2554 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2557 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2558 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2560 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2561 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2562 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2563 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2564 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2567 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2568 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
2570 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2571 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2572 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2573 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2574 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2579 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2580 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2582 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2583 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2584 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2585 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2586 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2589 ALU_END(*rT, 1/*CA*/, OE, Rc);
2590 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2592 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2593 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2594 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2595 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2596 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2597 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2602 ALU_END(*rT, 1/*CA*/, OE, Rc);
2603 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2605 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2606 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2607 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2608 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2609 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2613 ALU_END(*rT, 1/*CA*/, OE, Rc);
2614 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2616 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2617 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2618 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2619 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2620 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2625 ALU_END(*rT, 1/*CA*/, OE, Rc);
2626 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2628 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2629 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2630 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2631 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2632 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2636 ALU_END(*rT, 1/*CA*/, OE, Rc);
2637 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2639 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2640 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2641 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2642 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2643 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2648 ALU_END(*rT, 1/*CA*/, OE, Rc);
2649 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2651 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2652 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2653 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2654 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2655 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2658 ALU_END(*rT, 1/*CA*/, OE, Rc);
2659 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2661 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2662 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2663 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2664 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2665 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2669 ALU_END(*rT, 1/*CA*/, OE, Rc);
2670 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2672 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
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
2680 ALU_END(*rT,0/*CA*/,OE,Rc);
2681 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2683 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2684 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2685 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2686 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2687 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2688 signed_word prod = *rA * EXTS(SI);
2690 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2692 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2694 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2695 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2696 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2697 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2698 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2699 int64_t a = (int32_t)(*rA);
2700 int64_t b = (int32_t)(*rB);
2701 int64_t prod = a * b;
2702 signed_word t = prod;
2704 if (t != prod && OE)
2705 XER |= (xer_overflow | xer_summary_overflow);
2706 CR0_COMPARE(t, 0, Rc);
2707 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2709 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2711 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2712 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2713 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2714 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2715 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2716 int64_t a = (int32_t)(*rA);
2717 int64_t b = (int32_t)(*rB);
2718 int64_t prod = a * b;
2719 signed_word t = EXTRACTED64(prod, 0, 31);
2721 CR0_COMPARE(t, 0, Rc);
2722 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2724 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2726 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::mulhwu:Multiply High Word Unsigned
2727 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2728 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2729 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2730 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2731 uint64_t a = (uint32_t)(*rA);
2732 uint64_t b = (uint32_t)(*rB);
2733 uint64_t prod = a * b;
2734 signed_word t = EXTRACTED64(prod, 0, 31);
2736 CR0_COMPARE(t, 0, Rc);
2737 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2739 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2741 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2742 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2743 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2744 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2745 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2746 int64_t dividend = (int32_t)(*rA);
2747 int64_t divisor = (int32_t)(*rB);
2748 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2749 || (dividend == 0x80000000 && divisor == -1)) {
2751 XER |= (xer_overflow | xer_summary_overflow);
2752 CR0_COMPARE(0, 0, Rc);
2755 int64_t quotent = dividend / divisor;
2757 CR0_COMPARE((signed_word)quotent, 0, Rc);
2759 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2761 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2763 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2764 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2765 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2766 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2767 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2768 uint64_t dividend = (uint32_t)(*rA);
2769 uint64_t divisor = (uint32_t)(*rB);
2772 XER |= (xer_overflow | xer_summary_overflow);
2773 CR0_COMPARE(0, 0, Rc);
2776 uint64_t quotent = dividend / divisor;
2778 CR0_COMPARE((signed_word)quotent, 0, Rc);
2780 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2784 # I.3.3.10 Fixed-Point Compare Instructions
2787 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2788 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2789 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2790 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2791 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2792 if (!is_64bit_mode && L)
2793 program_interrupt(processor, cia,
2794 illegal_instruction_program_interrupt);
2797 signed_word b = EXTS(SI);
2802 CR_COMPARE(BF, a, b);
2804 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2806 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2807 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2808 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2809 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2810 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2811 if (!is_64bit_mode && L)
2812 program_interrupt(processor, cia,
2813 illegal_instruction_program_interrupt);
2825 CR_COMPARE(BF, a, b);
2827 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2829 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2830 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2831 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2832 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2833 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2834 if (!is_64bit_mode && L)
2835 program_interrupt(processor, cia,
2836 illegal_instruction_program_interrupt);
2839 unsigned_word b = UI;
2841 a = MASKED(*rA, 32, 63);
2844 CR_COMPARE(BF, a, b);
2846 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2848 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2849 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2850 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2851 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2852 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2853 if (!is_64bit_mode && L)
2854 program_interrupt(processor, cia,
2855 illegal_instruction_program_interrupt);
2860 a = MASKED(*rA, 32, 63);
2861 b = MASKED(*rB, 32, 63);
2867 CR_COMPARE(BF, a, b);
2869 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2873 # I.3.3.11 Fixed-Point Trap Instructions
2876 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2878 program_interrupt(processor, cia,
2879 illegal_instruction_program_interrupt);
2881 signed_word a = *rA;
2882 signed_word b = EXTS(SI);
2883 if ((a < b && TO{0})
2885 || (a == b && TO{2})
2886 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2887 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2889 program_interrupt(processor, cia,
2890 trap_program_interrupt);
2893 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2894 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2895 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2896 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2897 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2898 signed_word a = EXTENDED(*rA);
2899 signed_word b = EXTS(SI);
2900 if ((a < b && TO{0})
2902 || (a == b && TO{2})
2903 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2904 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2906 program_interrupt(processor, cia,
2907 trap_program_interrupt);
2909 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2911 program_interrupt(processor, cia,
2912 illegal_instruction_program_interrupt);
2914 signed_word a = *rA;
2915 signed_word b = *rB;
2916 if ((a < b && TO{0})
2918 || (a == b && TO{2})
2919 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2920 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2922 program_interrupt(processor, cia,
2923 trap_program_interrupt);
2926 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2927 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2928 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2929 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2930 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2931 signed_word a = EXTENDED(*rA);
2932 signed_word b = EXTENDED(*rB);
2933 if (TO == 12 && rA == rB) {
2934 ITRACE(trace_breakpoint, ("breakpoint\n"));
2935 cpu_halt(processor, cia, was_trap, 0);
2937 else if ((a < b && TO{0})
2939 || (a == b && TO{2})
2940 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2941 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2943 program_interrupt(processor, cia,
2944 trap_program_interrupt);
2947 # I.3.3.12 Fixed-Point Logical Instructions
2950 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2951 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2952 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2953 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2954 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2956 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2957 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2958 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2960 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2961 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2962 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2963 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2964 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2965 *rA = *rS & (UI << 16);
2966 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2967 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2968 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2970 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2971 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2972 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2973 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2974 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2976 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2977 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2979 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2980 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2981 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2982 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2983 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2984 *rA = *rS | (UI << 16);
2985 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2986 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2988 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2989 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2990 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2991 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2992 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2994 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2995 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2997 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2998 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2999 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3000 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3001 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3002 *rA = *rS ^ (UI << 16);
3003 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3004 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
3006 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
3007 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3008 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3009 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3010 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3012 CR0_COMPARE(*rA, 0, Rc);
3013 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3014 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3016 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
3017 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3018 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3019 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3020 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3022 CR0_COMPARE(*rA, 0, Rc);
3023 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3024 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3026 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
3027 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3028 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3029 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3030 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3032 CR0_COMPARE(*rA, 0, Rc);
3033 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3034 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3036 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
3037 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3038 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3039 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3040 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3042 CR0_COMPARE(*rA, 0, Rc);
3043 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3044 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3046 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
3047 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3048 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3049 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3050 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3052 CR0_COMPARE(*rA, 0, Rc);
3053 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3054 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3056 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
3057 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3058 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3059 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3060 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3061 *rA = ~(*rS ^ *rB); /* A === B */
3062 CR0_COMPARE(*rA, 0, Rc);
3063 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3064 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3066 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
3067 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3068 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3069 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3070 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3072 CR0_COMPARE(*rA, 0, Rc);
3073 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3074 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3076 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
3077 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3078 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3079 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3080 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3082 CR0_COMPARE(*rA, 0, Rc);
3083 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3084 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3086 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
3087 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3088 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3089 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3090 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3091 *rA = (signed_word)(int8_t)*rS;
3092 CR0_COMPARE(*rA, 0, Rc);
3093 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3094 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3096 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
3097 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3098 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3099 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3100 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3101 *rA = (signed_word)(int16_t)*rS;
3102 CR0_COMPARE(*rA, 0, Rc);
3103 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3104 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3106 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
3107 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3108 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3109 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3110 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3111 # *rA = (signed_word)(int32_t)*rS;
3112 # CR0_COMPARE(*rA, 0, Rc);
3114 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
3116 # uint64_t mask = BIT64(0);
3117 # uint64_t source = *rS;
3118 # while (!(source & mask) && mask != 0) {
3123 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3125 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
3126 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3127 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3128 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3129 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3131 uint32_t mask = BIT32(0);
3132 uint32_t source = *rS;
3133 while (!(source & mask) && mask != 0) {
3138 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3139 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3143 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
3146 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
3147 # long n = (sh_5 << 4) | sh_0_4;
3148 # unsigned_word r = ROTL64(*rS, n);
3149 # long b = (mb_5 << 4) | mb_0_4;
3150 # unsigned_word m = MASK(b, 63);
3151 # signed_word result = r & m;
3153 # ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3154 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3156 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
3157 # long n = (sh_5 << 4) | sh_0_4;
3158 # unsigned_word r = ROTL64(*rS, n);
3159 # long e = (me_5 << 4) | me_0_4;
3160 # unsigned_word m = MASK(0, e);
3161 # signed_word result = r & m;
3163 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3165 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
3166 # long n = (sh_5 << 4) | sh_0_4;
3167 # unsigned_word r = ROTL64(*rS, n);
3168 # long b = (mb_5 << 4) | mb_0_4;
3169 # unsigned_word m = MASK(0, (64-n));
3170 # signed_word result = r & m;
3172 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3174 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
3175 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3176 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3177 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3178 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3181 uint32_t r = ROTL32(s, n);
3182 uint32_t m = MASK(MB+32, ME+32);
3183 signed_word result = r & m;
3185 CR0_COMPARE(result, 0, Rc);
3187 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
3188 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
3189 (unsigned long)result, (unsigned long)CR));
3190 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3192 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
3193 # long n = MASKED(*rB, 58, 63);
3194 # unsigned_word r = ROTL64(*rS, n);
3195 # long b = (mb_5 << 4) | mb_0_4;
3196 # unsigned_word m = MASK(b, 63);
3197 # signed_word result = r & m;
3199 # CR0_COMPARE(result, 0, Rc);
3201 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
3202 # long n = MASKED(*rB, 58, 63);
3203 # unsigned_word r = ROTL64(*rS, n);
3204 # long e = (me_5 << 4) | me_0_4;
3205 # unsigned_word m = MASK(0, e);
3206 # signed_word result = r & m;
3208 # CR0_COMPARE(result, 0, Rc);
3210 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
3211 long n = MASKED(*rB, 59, 63);
3212 uint32_t r = ROTL32(*rS, n);
3213 uint32_t m = MASK(MB+32, ME+32);
3214 signed_word result = r & m;
3216 CR0_COMPARE(result, 0, Rc);
3218 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
3219 # long n = (sh_5 << 4) | sh_0_4;
3220 # unsigned_word r = ROTL64(*rS, n);
3221 # long b = (mb_5 << 4) | mb_0_4;
3222 # unsigned_word m = MASK(b, (64-n));
3223 # signed_word result = (r & m) | (*rA & ~m)
3225 # CR0_COMPARE(result, 0, Rc);
3227 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
3228 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3229 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3230 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3231 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3233 uint32_t r = ROTL32(*rS, n);
3234 uint32_t m = MASK(MB+32, ME+32);
3235 signed_word result = (r & m) | (*rA & ~m);
3237 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
3238 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
3239 (unsigned long)result));
3240 CR0_COMPARE(result, 0, Rc);
3241 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3244 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
3246 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
3247 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3248 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3249 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3250 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3251 int n = MASKED(*rB, 58, 63);
3252 uint32_t source = *rS;
3253 signed_word shifted;
3255 shifted = (source << n);
3259 CR0_COMPARE(shifted, 0, Rc);
3261 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3262 n, (unsigned long)source, (unsigned long)shifted));
3263 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3265 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3267 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
3268 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3269 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3270 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3271 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3272 int n = MASKED(*rB, 58, 63);
3273 uint32_t source = *rS;
3274 signed_word shifted;
3276 shifted = (source >> n);
3280 CR0_COMPARE(shifted, 0, Rc);
3282 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3283 n, (unsigned long)source, (unsigned long)shifted));
3284 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3286 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3288 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3289 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3290 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3291 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3292 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3294 signed_word r = ROTL32(*rS, /*64*/32-n);
3295 signed_word m = MASK(n+32, 63);
3296 int S = MASKED(*rS, 32, 32);
3297 signed_word shifted = (r & m) | (S ? ~m : 0);
3299 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3303 CR0_COMPARE(shifted, 0, Rc);
3304 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3305 (long)*rA, (long)*rA, (long)XER));
3306 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3308 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3310 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3311 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3312 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3313 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3314 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3316 int n = MASKED(*rB, 59, 63);
3317 int32_t source = (int32_t)*rS; /* signed to keep sign bit */
3318 int S = (MASKED(*rS,32,32) != 0);
3319 int64_t r = ((uint64_t) source);
3320 r = ((uint64_t) source) << 32 | (uint32_t) source;
3322 if (MASKED(*rB,58,58) == 0)
3323 mask = (uint64_t) MASK64(n+32,63);
3325 mask = (uint64_t) 0;
3326 *rA = (signed_word) ((r & mask) | (((int64_t) -1*S) & ~mask)); /* if 64bit will sign extend */
3327 if (S && (MASKED(r & ~mask,32,63)!=0))
3331 CR0_COMPARE(*rA, 0, Rc);
3332 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3333 (long)*rA, (long)*rA, (long)XER));
3334 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3337 # I.3.3.14 Move to/from System Register Instructions
3340 0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3341 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3342 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3343 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3344 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3345 int n = (SPR{5:9} << 5) | SPR{0:4};
3346 if (SPR{0} && IS_PROBLEM_STATE(processor))
3347 program_interrupt(processor, cia,
3348 privileged_instruction_program_interrupt);
3349 else if (!spr_is_valid(n)
3350 || spr_is_readonly(n))
3351 program_interrupt(processor, cia,
3352 illegal_instruction_program_interrupt);
3354 spreg new_val = (spr_length(n) == 64
3356 : MASKED(*rS, 32, 63));
3357 /* HACK - time base registers need to be updated immediately */
3358 if (WITH_TIME_BASE) {
3361 cpu_set_time_base(processor,
3362 (MASKED64(cpu_get_time_base(processor), 32, 63)
3363 | INSERTED64(new_val, 0, 31)));
3366 cpu_set_time_base(processor,
3367 (MASKED64(cpu_get_time_base(processor), 0, 31)
3368 | INSERTED64(new_val, 32, 63)));
3371 cpu_set_decrementer(processor, new_val);
3382 PPC_INSN_TO_SPR(RS_BITMASK, n);
3384 0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3385 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3386 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3387 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3388 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3389 int n = (SPR{5:9} << 5) | SPR{0:4};
3390 if (SPR{0} && IS_PROBLEM_STATE(processor))
3391 program_interrupt(processor, cia,
3392 privileged_instruction_program_interrupt);
3393 else if (!spr_is_valid(n))
3394 program_interrupt(processor, cia,
3395 illegal_instruction_program_interrupt);
3397 /* HACK - time base registers need to be calculated */
3398 if (WITH_TIME_BASE) {
3401 *rT = cpu_get_decrementer(processor);
3404 if (is_64bit_implementation) *rT = TB;
3405 else *rT = EXTRACTED64(TB, 32, 63);
3408 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
3409 else *rT = EXTRACTED64(TB, 0, 31);
3413 /* NOTE - these SPR's are not readable. Use mftb[ul] */
3423 PPC_INSN_FROM_SPR(RT_BITMASK, n);
3425 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3426 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3427 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3428 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3429 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3434 unsigned_word mask = 0;
3436 for (f = 0; f < 8; f++) {
3437 if (FXM & (0x80 >> f))
3438 mask |= (0xf << 4*(7-f));
3440 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3442 PPC_INSN_MTCR(RS_BITMASK, FXM);
3444 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3445 # CR_SET(BF, EXTRACTED32(XER, 0, 3));
3446 # MBLIT32(XER, 0, 3, 0);
3448 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3449 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3450 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3451 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3452 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3454 PPC_INSN_MFCR(RT_BITMASK);
3457 # I.4.6.2 Floating-Point Load Instructions
3460 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3461 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3462 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3463 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3464 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3470 *frT = DOUBLE(MEM(unsigned, EA, 4));
3471 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3473 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3474 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3475 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3476 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3477 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3483 *frT = DOUBLE(MEM(unsigned, EA, 4));
3484 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3486 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3487 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3488 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3489 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3490 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3493 program_interrupt(processor, cia,
3494 illegal_instruction_program_interrupt);
3496 *frT = DOUBLE(MEM(unsigned, EA, 4));
3498 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3500 0.31,6.FRT,11.RA,16.RB,21.567,31./:X:f::Load Floating-Point Single with Update Indexed
3501 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3502 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3503 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3504 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3507 program_interrupt(processor, cia,
3508 illegal_instruction_program_interrupt);
3510 *frT = DOUBLE(MEM(unsigned, EA, 4));
3512 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3514 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3515 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3516 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3517 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3518 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3524 *frT = MEM(unsigned, EA, 8);
3525 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3527 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3528 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3529 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3530 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3531 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3537 *frT = MEM(unsigned, EA, 8);
3538 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3540 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3541 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3542 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3543 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3544 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3547 program_interrupt(processor, cia,
3548 illegal_instruction_program_interrupt);
3550 *frT = MEM(unsigned, EA, 8);
3552 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3554 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3555 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3556 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3557 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3558 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3561 program_interrupt(processor, cia,
3562 illegal_instruction_program_interrupt);
3564 *frT = MEM(unsigned, EA, 8);
3566 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3570 # I.4.6.3 Floating-Point Store Instructions
3573 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3574 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3575 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3576 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3577 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3583 STORE(EA, 4, SINGLE(*frS));
3584 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3586 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3587 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3588 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3589 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3590 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3596 STORE(EA, 4, SINGLE(*frS));
3597 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3599 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3600 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3601 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3602 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3603 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3606 program_interrupt(processor, cia,
3607 illegal_instruction_program_interrupt);
3609 STORE(EA, 4, SINGLE(*frS));
3611 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3613 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3614 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3615 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3616 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3617 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3620 program_interrupt(processor, cia,
3621 illegal_instruction_program_interrupt);
3623 STORE(EA, 4, SINGLE(*frS));
3625 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3627 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3628 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3629 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3630 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3631 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3638 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3640 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3641 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3642 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3643 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3644 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3651 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3653 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point Integer Word Indexed
3654 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3655 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3656 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3663 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3665 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3666 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3667 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3668 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3669 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3672 program_interrupt(processor, cia,
3673 illegal_instruction_program_interrupt);
3677 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3679 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3680 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3681 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3682 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3683 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3686 program_interrupt(processor, cia,
3687 illegal_instruction_program_interrupt);
3691 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3695 # I.4.6.4 Floating-Point Move Instructions
3698 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3699 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3700 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3701 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3702 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3705 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3707 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3708 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3709 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3710 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3711 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3712 *frT = *frB ^ BIT64(0);
3714 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3716 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3717 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3718 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3719 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3720 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3721 *frT = *frB & ~BIT64(0);
3723 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3725 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3726 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3727 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3728 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3729 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3730 *frT = *frB | BIT64(0);
3732 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3736 # I.4.6.5 Floating-Point Arithmetic Instructions
3739 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3740 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3741 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3742 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3743 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3745 if (is_invalid_operation(processor, cia,
3747 fpscr_vxsnan | fpscr_vxisi,
3750 invalid_arithemetic_operation(processor, cia,
3752 0, /*instruction_is_frsp*/
3753 0, /*instruction_is_convert_to_64bit*/
3754 0, /*instruction_is_convert_to_32bit*/
3755 0); /*single-precision*/
3759 double s = *(double*)frA + *(double*)frB;
3763 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3765 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3766 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3767 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3768 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3769 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3771 if (is_invalid_operation(processor, cia,
3773 fpscr_vxsnan | fpscr_vxisi,
3776 invalid_arithemetic_operation(processor, cia,
3778 0, /*instruction_is_frsp*/
3779 0, /*instruction_is_convert_to_64bit*/
3780 0, /*instruction_is_convert_to_32bit*/
3781 1); /*single-precision*/
3785 float s = *(double*)frA + *(double*)frB;
3789 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3791 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3792 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3793 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3794 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3795 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3797 if (is_invalid_operation(processor, cia,
3799 fpscr_vxsnan | fpscr_vxisi,
3802 invalid_arithemetic_operation(processor, cia,
3804 0, /*instruction_is_frsp*/
3805 0, /*instruction_is_convert_to_64bit*/
3806 0, /*instruction_is_convert_to_32bit*/
3807 0); /*single-precision*/
3811 double s = *(double*)frA - *(double*)frB;
3815 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3817 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3818 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3819 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3820 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3821 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3823 if (is_invalid_operation(processor, cia,
3825 fpscr_vxsnan | fpscr_vxisi,
3828 invalid_arithemetic_operation(processor, cia,
3830 0, /*instruction_is_frsp*/
3831 0, /*instruction_is_convert_to_64bit*/
3832 0, /*instruction_is_convert_to_32bit*/
3833 1); /*single-precision*/
3837 float s = *(double*)frA - *(double*)frB;
3841 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3843 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3844 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3845 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3846 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3847 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3849 if (is_invalid_operation(processor, cia,
3851 fpscr_vxsnan | fpscr_vximz,
3854 invalid_arithemetic_operation(processor, cia,
3856 0, /*instruction_is_frsp*/
3857 0, /*instruction_is_convert_to_64bit*/
3858 0, /*instruction_is_convert_to_32bit*/
3859 0); /*single-precision*/
3863 double s = *(double*)frA * *(double*)frC;
3867 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3869 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3870 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3871 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3872 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3873 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3875 if (is_invalid_operation(processor, cia,
3877 fpscr_vxsnan | fpscr_vximz,
3880 invalid_arithemetic_operation(processor, cia,
3882 0, /*instruction_is_frsp*/
3883 0, /*instruction_is_convert_to_64bit*/
3884 0, /*instruction_is_convert_to_32bit*/
3885 1); /*single-precision*/
3889 float s = *(double*)frA * *(double*)frC;
3893 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3895 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3896 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3897 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3898 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3899 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3901 if (is_invalid_operation(processor, cia,
3903 fpscr_vxsnan | fpscr_vxzdz,
3906 invalid_arithemetic_operation(processor, cia,
3908 0, /*instruction_is_frsp*/
3909 0, /*instruction_is_convert_to_64bit*/
3910 0, /*instruction_is_convert_to_32bit*/
3911 0); /*single-precision*/
3913 else if (is_invalid_zero_divide (processor, cia,
3916 invalid_zero_divide_operation (processor, cia,
3922 double s = *(double*)frA / *(double*)frB;
3926 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3928 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3929 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3930 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3931 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3932 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3934 if (is_invalid_operation(processor, cia,
3936 fpscr_vxsnan | fpscr_vxzdz,
3939 invalid_arithemetic_operation(processor, cia,
3941 0, /*instruction_is_frsp*/
3942 0, /*instruction_is_convert_to_64bit*/
3943 0, /*instruction_is_convert_to_32bit*/
3944 1); /*single-precision*/
3946 else if (is_invalid_zero_divide (processor, cia,
3949 invalid_zero_divide_operation (processor, cia,
3955 float s = *(double*)frA / *(double*)frB;
3959 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3961 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3962 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3963 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3964 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3965 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3967 double product; /*HACK! - incorrectly loosing precision ... */
3968 /* compute the multiply */
3969 if (is_invalid_operation(processor, cia,
3971 fpscr_vxsnan | fpscr_vximz,
3974 union { double d; uint64_t u; } tmp;
3975 invalid_arithemetic_operation(processor, cia,
3976 &tmp.u, *frA, 0, *frC,
3977 0, /*instruction_is_frsp*/
3978 0, /*instruction_is_convert_to_64bit*/
3979 0, /*instruction_is_convert_to_32bit*/
3980 0); /*single-precision*/
3985 product = *(double*)frA * *(double*)frC;
3987 /* compute the add */
3988 if (is_invalid_operation(processor, cia,
3990 fpscr_vxsnan | fpscr_vxisi,
3993 invalid_arithemetic_operation(processor, cia,
3994 frT, product, *frB, 0,
3995 0, /*instruction_is_frsp*/
3996 0, /*instruction_is_convert_to_64bit*/
3997 0, /*instruction_is_convert_to_32bit*/
3998 0); /*single-precision*/
4002 double s = product + *(double*)frB;
4006 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4008 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
4009 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4010 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4011 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4012 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4014 float product; /*HACK! - incorrectly loosing precision ... */
4015 /* compute the multiply */
4016 if (is_invalid_operation(processor, cia,
4018 fpscr_vxsnan | fpscr_vximz,
4021 union { double d; uint64_t u; } tmp;
4022 invalid_arithemetic_operation(processor, cia,
4023 &tmp.u, *frA, 0, *frC,
4024 0, /*instruction_is_frsp*/
4025 0, /*instruction_is_convert_to_64bit*/
4026 0, /*instruction_is_convert_to_32bit*/
4027 0); /*single-precision*/
4032 product = *(double*)frA * *(double*)frC;
4034 /* compute the add */
4035 if (is_invalid_operation(processor, cia,
4037 fpscr_vxsnan | fpscr_vxisi,
4040 invalid_arithemetic_operation(processor, cia,
4041 frT, product, *frB, 0,
4042 0, /*instruction_is_frsp*/
4043 0, /*instruction_is_convert_to_64bit*/
4044 0, /*instruction_is_convert_to_32bit*/
4045 0); /*single-precision*/
4049 float s = product + *(double*)frB;
4050 *(double*)frT = (double)s;
4053 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4055 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
4056 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4057 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4058 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4059 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4061 double product; /*HACK! - incorrectly loosing precision ... */
4062 /* compute the multiply */
4063 if (is_invalid_operation(processor, cia,
4065 fpscr_vxsnan | fpscr_vximz,
4068 union { double d; uint64_t u; } tmp;
4069 invalid_arithemetic_operation(processor, cia,
4070 &tmp.u, *frA, 0, *frC,
4071 0, /*instruction_is_frsp*/
4072 0, /*instruction_is_convert_to_64bit*/
4073 0, /*instruction_is_convert_to_32bit*/
4074 0); /*single-precision*/
4079 product = *(double*)frA * *(double*)frC;
4081 /* compute the subtract */
4082 if (is_invalid_operation(processor, cia,
4084 fpscr_vxsnan | fpscr_vxisi,
4087 invalid_arithemetic_operation(processor, cia,
4088 frT, product, *frB, 0,
4089 0, /*instruction_is_frsp*/
4090 0, /*instruction_is_convert_to_64bit*/
4091 0, /*instruction_is_convert_to_32bit*/
4092 0); /*single-precision*/
4096 double s = product - *(double*)frB;
4100 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4102 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
4103 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4104 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4105 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4106 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4108 float product; /*HACK! - incorrectly loosing precision ... */
4109 /* compute the multiply */
4110 if (is_invalid_operation(processor, cia,
4112 fpscr_vxsnan | fpscr_vximz,
4115 union { double d; uint64_t u; } tmp;
4116 invalid_arithemetic_operation(processor, cia,
4117 &tmp.u, *frA, 0, *frC,
4118 0, /*instruction_is_frsp*/
4119 0, /*instruction_is_convert_to_64bit*/
4120 0, /*instruction_is_convert_to_32bit*/
4121 0); /*single-precision*/
4126 product = *(double*)frA * *(double*)frC;
4128 /* compute the subtract */
4129 if (is_invalid_operation(processor, cia,
4131 fpscr_vxsnan | fpscr_vxisi,
4134 invalid_arithemetic_operation(processor, cia,
4135 frT, product, *frB, 0,
4136 0, /*instruction_is_frsp*/
4137 0, /*instruction_is_convert_to_64bit*/
4138 0, /*instruction_is_convert_to_32bit*/
4139 0); /*single-precision*/
4143 float s = product - *(double*)frB;
4144 *(double*)frT = (double)s;
4147 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4149 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
4150 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4151 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4152 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4153 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4155 double product; /*HACK! - incorrectly loosing precision ... */
4156 /* compute the multiply */
4157 if (is_invalid_operation(processor, cia,
4159 fpscr_vxsnan | fpscr_vximz,
4162 union { double d; uint64_t u; } tmp;
4163 invalid_arithemetic_operation(processor, cia,
4164 &tmp.u, *frA, 0, *frC,
4165 0, /*instruction_is_frsp*/
4166 0, /*instruction_is_convert_to_64bit*/
4167 0, /*instruction_is_convert_to_32bit*/
4168 0); /*single-precision*/
4173 product = *(double*)frA * *(double*)frC;
4175 /* compute the add */
4176 if (is_invalid_operation(processor, cia,
4178 fpscr_vxsnan | fpscr_vxisi,
4181 invalid_arithemetic_operation(processor, cia,
4182 frT, product, *frB, 0,
4183 0, /*instruction_is_frsp*/
4184 0, /*instruction_is_convert_to_64bit*/
4185 0, /*instruction_is_convert_to_32bit*/
4186 0); /*single-precision*/
4190 double s = -(product + *(double*)frB);
4194 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4196 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
4197 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4198 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4199 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4200 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4202 float product; /*HACK! - incorrectly loosing precision ... */
4203 /* compute the multiply */
4204 if (is_invalid_operation(processor, cia,
4206 fpscr_vxsnan | fpscr_vximz,
4209 union { double d; uint64_t u; } tmp;
4210 invalid_arithemetic_operation(processor, cia,
4211 &tmp.u, *frA, 0, *frC,
4212 0, /*instruction_is_frsp*/
4213 0, /*instruction_is_convert_to_64bit*/
4214 0, /*instruction_is_convert_to_32bit*/
4215 0); /*single-precision*/
4220 product = *(double*)frA * *(double*)frC;
4222 /* compute the add */
4223 if (is_invalid_operation(processor, cia,
4225 fpscr_vxsnan | fpscr_vxisi,
4228 invalid_arithemetic_operation(processor, cia,
4229 frT, product, *frB, 0,
4230 0, /*instruction_is_frsp*/
4231 0, /*instruction_is_convert_to_64bit*/
4232 0, /*instruction_is_convert_to_32bit*/
4233 0); /*single-precision*/
4237 float s = -(product + *(double*)frB);
4238 *(double*)frT = (double)s;
4241 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4243 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
4244 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4245 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4246 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4247 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4249 double product; /*HACK! - incorrectly loosing precision ... */
4250 /* compute the multiply */
4251 if (is_invalid_operation(processor, cia,
4253 fpscr_vxsnan | fpscr_vximz,
4256 union { double d; uint64_t u; } tmp;
4257 invalid_arithemetic_operation(processor, cia,
4258 &tmp.u, *frA, 0, *frC,
4259 0, /*instruction_is_frsp*/
4260 0, /*instruction_is_convert_to_64bit*/
4261 0, /*instruction_is_convert_to_32bit*/
4262 0); /*single-precision*/
4267 product = *(double*)frA * *(double*)frC;
4269 /* compute the subtract */
4270 if (is_invalid_operation(processor, cia,
4272 fpscr_vxsnan | fpscr_vxisi,
4275 invalid_arithemetic_operation(processor, cia,
4276 frT, product, *frB, 0,
4277 0, /*instruction_is_frsp*/
4278 0, /*instruction_is_convert_to_64bit*/
4279 0, /*instruction_is_convert_to_32bit*/
4280 0); /*single-precision*/
4284 double s = -(product - *(double*)frB);
4288 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4290 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
4291 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4292 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4293 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4294 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4296 float product; /*HACK! - incorrectly loosing precision ... */
4297 /* compute the multiply */
4298 if (is_invalid_operation(processor, cia,
4300 fpscr_vxsnan | fpscr_vximz,
4303 union { double d; uint64_t u; } tmp;
4304 invalid_arithemetic_operation(processor, cia,
4305 &tmp.u, *frA, 0, *frC,
4306 0, /*instruction_is_frsp*/
4307 0, /*instruction_is_convert_to_64bit*/
4308 0, /*instruction_is_convert_to_32bit*/
4309 0); /*single-precision*/
4314 product = *(double*)frA * *(double*)frC;
4316 /* compute the subtract */
4317 if (is_invalid_operation(processor, cia,
4319 fpscr_vxsnan | fpscr_vxisi,
4322 invalid_arithemetic_operation(processor, cia,
4323 frT, product, *frB, 0,
4324 0, /*instruction_is_frsp*/
4325 0, /*instruction_is_convert_to_64bit*/
4326 0, /*instruction_is_convert_to_32bit*/
4327 0); /*single-precision*/
4331 float s = -(product - *(double*)frB);
4332 *(double*)frT = (double)s;
4335 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4339 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4342 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4343 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4344 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4345 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4346 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4351 /* split off cases for what to do */
4352 if (EXTRACTED64(*frB, 1, 11) < 897
4353 && EXTRACTED64(*frB, 1, 63) > 0) {
4354 if ((FPSCR & fpscr_ue) == 0) GOTO(Disabled_Exponent_Underflow);
4355 if ((FPSCR & fpscr_ue) != 0) GOTO(Enabled_Exponent_Underflow);
4357 if (EXTRACTED64(*frB, 1, 11) > 1150
4358 && EXTRACTED64(*frB, 1, 11) < 2047) {
4359 if ((FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4360 if ((FPSCR & fpscr_oe) != 0) GOTO(Enabled_Exponent_Overflow);
4362 if (EXTRACTED64(*frB, 1, 11) > 896
4363 && EXTRACTED64(*frB, 1, 11) < 1151) GOTO(Normal_Operand);
4364 if (EXTRACTED64(*frB, 1, 63) == 0) GOTO(Zero_Operand);
4365 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4366 if (EXTRACTED64(*frB, 12, 63) == 0) GOTO(Infinity_Operand);
4367 if (EXTRACTED64(*frB, 12, 12) == 1) GOTO(QNaN_Operand);
4368 if (EXTRACTED64(*frB, 12, 12) == 0
4369 && EXTRACTED64(*frB, 13, 63) > 0) GOTO(SNaN_Operand);
4372 LABEL(Disabled_Exponent_Underflow):
4373 sign = EXTRACTED64(*frB, 0, 0);
4374 if (EXTRACTED64(*frB, 1, 11) == 0) {
4376 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4378 if (EXTRACTED64(*frB, 1, 11) > 0) {
4379 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4380 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4382 /* G|R|X == zero from above */
4383 while (exp < -126) {
4385 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4386 | MASKED64(frac_grx, 55, 55));
4388 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4389 Round_Single(processor, sign, &exp, &frac_grx);
4390 FPSCR_SET_XX(FPSCR & fpscr_fi);
4391 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4392 *frT = INSERTED64(sign, 0, 0);
4393 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4394 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4396 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4397 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4398 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4399 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4401 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4402 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4403 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4405 /*Normalize_Operand:*/
4406 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4408 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4410 *frT = (INSERTED64(sign, 0, 0)
4411 | INSERTED64(exp + 1023, 1, 11)
4412 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4416 LABEL(Enabled_Exponent_Underflow):
4418 sign = EXTRACTED64(*frB, 0, 0);
4419 if (EXTRACTED64(*frB, 1, 11) == 0) {
4421 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4423 if (EXTRACTED64(*frB, 1, 11) > 0) {
4424 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4425 frac_grx = (BIT64(0) |
4426 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4428 /*Normalize_Operand:*/
4429 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4431 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4433 Round_Single(processor, sign, &exp, &frac_grx);
4434 FPSCR_SET_XX(FPSCR & fpscr_fi);
4436 *frT = (INSERTED64(sign, 0, 0)
4437 | INSERTED64(exp + 1023, 1, 11)
4438 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4439 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4440 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4443 LABEL(Disabled_Exponent_Overflow):
4445 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4446 if (EXTRACTED64(*frB, 0, 0) == 0) {
4447 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4448 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4450 if (EXTRACTED64(*frB, 0, 0) == 1) {
4451 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4452 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4455 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4456 if (EXTRACTED64(*frB, 0, 0) == 0) {
4457 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4458 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4460 if (EXTRACTED64(*frB, 0, 0) == 1) {
4461 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4462 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4465 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4466 if (EXTRACTED64(*frB, 0, 0) == 0) {
4467 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4468 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4470 if (EXTRACTED64(*frB, 0, 0) == 1) {
4471 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4472 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4475 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4476 if (EXTRACTED64(*frB, 0, 0) == 0) {
4477 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4478 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4480 if (EXTRACTED64(*frB, 0, 0) == 1) {
4481 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4482 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4485 /* FPSCR[FR] <- undefined */
4490 LABEL(Enabled_Exponent_Overflow):
4491 sign = EXTRACTED64(*frB, 0, 0);
4492 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4493 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4494 Round_Single(processor, sign, &exp, &frac_grx);
4495 FPSCR_SET_XX(FPSCR & fpscr_fi);
4497 LABEL(Enabled_Overflow):
4500 *frT = (INSERTED64(sign, 0, 0)
4501 | INSERTED64(exp + 1023, 1, 11)
4502 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4503 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4504 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4507 LABEL(Zero_Operand):
4509 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4510 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4515 LABEL(Infinity_Operand):
4517 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4518 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4523 LABEL(QNaN_Operand):
4524 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4525 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4530 LABEL(SNaN_Operand):
4531 FPSCR_OR_VX(fpscr_vxsnan);
4532 if ((FPSCR & fpscr_ve) == 0) {
4533 *frT = (MASKED64(*frB, 0, 11)
4535 | MASKED64(*frB, 13, 34));
4536 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4542 LABEL(Normal_Operand):
4543 sign = EXTRACTED64(*frB, 0, 0);
4544 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4545 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4546 Round_Single(processor, sign, &exp, &frac_grx);
4547 FPSCR_SET_XX(FPSCR & fpscr_fi);
4548 if (exp > 127 && (FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4549 if (exp > 127 && (FPSCR & fpscr_oe) != 0) GOTO(Enabled_Overflow);
4550 *frT = (INSERTED64(sign, 0, 0)
4551 | INSERTED64(exp + 1023, 1, 11)
4552 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4553 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4554 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4558 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4561 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4562 floating_point_assist_interrupt(processor, cia);
4564 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4565 floating_point_assist_interrupt(processor, cia);
4567 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4568 floating_point_assist_interrupt(processor, cia);
4570 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4571 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4572 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4573 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4574 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4576 convert_to_integer(processor, cia,
4578 fpscr_rn_round_towards_zero, 32);
4580 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4582 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4583 int sign = EXTRACTED64(*frB, 0, 0);
4585 uint64_t frac = *frB;
4587 if (frac == 0) GOTO(Zero_Operand);
4588 if (sign == 1) frac = ~frac + 1;
4589 while (EXTRACTED64(frac, 0, 0) == 0) {
4590 /*??? do the loop 0 times if (FRB) = max negative integer */
4591 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4594 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4595 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4596 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4597 *frT = (INSERTED64(sign, 0, 0)
4598 | INSERTED64(exp + 1023, 1, 11)
4599 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4602 LABEL(Zero_Operand):
4605 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4610 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4614 # I.4.6.7 Floating-Point Compare Instructions
4617 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4618 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4619 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4620 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4621 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4624 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4625 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4626 else if (is_less_than(frA, frB))
4627 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4628 else if (is_greater_than(frA, frB))
4629 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4631 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4633 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4634 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4635 FPSCR_OR_VX(fpscr_vxsnan);
4637 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4639 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4640 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4641 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4642 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4643 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4646 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4647 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4648 else if (is_less_than(frA, frB))
4649 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4650 else if (is_greater_than(frA, frB))
4651 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4653 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4655 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4656 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4657 FPSCR_OR_VX(fpscr_vxsnan);
4658 if ((FPSCR & fpscr_ve) == 0)
4659 FPSCR_OR_VX(fpscr_vxvc);
4661 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4662 FPSCR_OR_VX(fpscr_vxvc);
4665 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4669 # I.4.6.8 Floating-Point Status and Control Register Instructions
4672 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4677 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4679 unsigned field = FPSCR_FIELD(BFA);
4681 FPSCR_SET(BFA, 0); /* FPSCR_END fixes up FEX/VX */
4684 0.63,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4689 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4692 for (i = 0; i < 8; i++) {
4693 if ((FLM & BIT8(i))) {
4694 FPSCR &= ~MASK32(i*4, i*4+3);
4695 FPSCR |= MASKED32(*frB, i*4, i*4+3);
4700 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4702 uint32_t bit = BIT32(BT);
4706 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4708 uint32_t bit = BIT32(BT);
4711 if ((bit & fpscr_vx_bits))
4713 /* note - omit vx bit */
4714 if ((bit & (fpscr_ox | fpscr_ux | fpscr_zx | fpscr_xx)))
4720 # I.A.1.2 Floating-Point Arithmetic Instructions
4723 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root
4724 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4726 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root Single
4727 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4729 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f,o::Floating Reciprocal Estimate Single
4730 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4732 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f,o::Floating Reciprocal Square Root Estimate
4733 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4736 # I.A.1.3 Floating-Point Select Instruction
4739 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f,o::Floating Select
4740 *601: PPC_UNIT_BAD, PPC_UNIT_BAD, 0, 0, 0
4741 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4742 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4743 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4744 if (CURRENT_MODEL == MODEL_ppc601) {
4745 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4749 if (is_NaN(*frA, 0) || is_less_than (frA, &zero)) *frT = *frB;
4752 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4756 # II.3.2 Cache Management Instructions
4759 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4760 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4761 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4762 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4763 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4764 /* blindly flush all instruction cache entries */
4765 #if WITH_IDECODE_CACHE_SIZE
4766 cpu_flush_icache(processor);
4768 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4770 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4771 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4772 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4773 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4774 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4775 cpu_synchronize_context(processor, cia);
4776 PPC_INSN_INT(0, 0, 0);
4780 # II.3.2.2 Data Cache Instructions
4783 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4784 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4785 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4786 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4787 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4788 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4789 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4791 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4792 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4793 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4794 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4795 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4796 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4797 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4799 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4800 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4801 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4802 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4803 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4804 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4805 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4807 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4808 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4809 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4810 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4811 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4812 TRACE(trace_tbd,("Data Cache Block Store\n"));
4813 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4815 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4816 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4817 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4818 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4819 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4820 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4821 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4824 # II.3.3 Enforce In-order Execution of I/O Instruction
4827 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4828 /* Since this model has no instruction overlap
4829 this instruction need do nothing */
4832 # II.4.1 Time Base Instructions
4835 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4836 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4837 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4838 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4839 int n = (tbr{5:9} << 5) | tbr{0:4};
4841 if (is_64bit_implementation) *rT = TB;
4842 else *rT = EXTRACTED64(TB, 32, 63);
4844 else if (n == 269) {
4845 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4846 else *rT = EXTRACTED64(TB, 0, 31);
4849 program_interrupt(processor, cia,
4850 illegal_instruction_program_interrupt);
4854 # III.2.3.1 System Linkage Instructions
4857 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4858 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4859 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4860 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4861 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4862 if (IS_PROBLEM_STATE(processor)) {
4863 program_interrupt(processor, cia,
4864 privileged_instruction_program_interrupt);
4867 MSR = (MASKED(SRR1, 0, 32)
4868 | MASKED(SRR1, 37, 41)
4869 | MASKED(SRR1, 48, 63));
4870 NIA = MASKED(SRR0, 0, 61);
4871 cpu_synchronize_context(processor, cia);
4872 check_masked_interrupts(processor);
4876 # III.3.4.1 Move to/from System Register Instructions
4879 #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4880 #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4881 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4882 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4883 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4884 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4885 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4886 if (IS_PROBLEM_STATE(processor))
4887 program_interrupt(processor, cia,
4888 privileged_instruction_program_interrupt);
4891 check_masked_interrupts(processor);
4894 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4895 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4896 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4897 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4898 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4899 if (IS_PROBLEM_STATE(processor))
4900 program_interrupt(processor, cia,
4901 privileged_instruction_program_interrupt);
4904 check_masked_interrupts(processor);
4909 # III.4.11.1 Cache Management Instructions
4912 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4913 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4914 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4915 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4916 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4917 if (IS_PROBLEM_STATE(processor))
4918 program_interrupt(processor, cia,
4919 privileged_instruction_program_interrupt);
4921 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4924 # III.4.11.2 Segment Register Manipulation Instructions
4927 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4928 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4929 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4930 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4931 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4932 if (IS_PROBLEM_STATE(processor))
4933 program_interrupt(processor, cia,
4934 privileged_instruction_program_interrupt);
4938 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4939 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4940 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4941 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4942 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4943 if (IS_PROBLEM_STATE(processor))
4944 program_interrupt(processor, cia,
4945 privileged_instruction_program_interrupt);
4947 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4949 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4950 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4951 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4952 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4953 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4954 if (IS_PROBLEM_STATE(processor))
4955 program_interrupt(processor, cia,
4956 privileged_instruction_program_interrupt);
4960 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4961 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4962 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4963 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4964 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4965 if (IS_PROBLEM_STATE(processor))
4966 program_interrupt(processor, cia,
4967 privileged_instruction_program_interrupt);
4969 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4973 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4976 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4978 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4980 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4981 if (IS_PROBLEM_STATE(processor))
4982 program_interrupt(processor, cia,
4983 privileged_instruction_program_interrupt);
4988 proc = psim_cpu(cpu_system(processor), nr);
4989 if (proc == NULL) break;
4990 cpu_page_tlb_invalidate_entry(proc, *rB);
4995 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4996 if (IS_PROBLEM_STATE(processor))
4997 program_interrupt(processor, cia,
4998 privileged_instruction_program_interrupt);
5003 proc = psim_cpu(cpu_system(processor), nr);
5004 if (proc == NULL) break;
5005 cpu_page_tlb_invalidate_all(proc);
5010 0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
5011 /* nothing happens here - always in sync */
5014 # III.A.1.2 External Access Instructions
5017 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
5019 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
5021 :include:::altivec.igen
5022 :include:::e500.igen