2 # This file is part of the program psim.
4 # Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
8 # The pseudo-code that appears below, translated into C, was copied
9 # by Andrew Cagney of Moss Vale, Australia.
11 # This pseudo-code is copied by permission from the publication
12 # "The PowerPC Architecture: A Specification for A New Family of
13 # RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by
14 # International Business Machines Corporation.
16 # THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER
17 # EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES
18 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 # This program is free software; you can redistribute it and/or modify
23 # it under the terms of the GNU General Public License as published by
24 # the Free Software Foundation; either version 2 of the License, or
25 # (at your option) any later version.
27 # This program is distributed in the hope that it will be useful,
28 # but WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 # GNU General Public License for more details.
32 # You should have received a copy of the GNU General Public License
33 # along with this program; if not, write to the Free Software
34 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 # 1 Instruction format as a `start-bit,content' pairs.
42 # the content is one of a digit, field name or `/' (aka.0)
46 # 3 Flags: 64 - 64bit only
47 # f - floating point enabled required
54 # For flags marked 'model', the fields are interpreted as follows:
62 # 4 String name for model
64 # 5 Specific CPU model, must be an identifier
66 # 6 Comma separated list of functional units
69 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
70 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
71 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
72 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
76 typedef enum _ppc_function_unit {
77 PPC_UNIT_BAD, /* unknown function unit */
78 PPC_UNIT_IU, /* integer unit (601/603 style) */
79 PPC_UNIT_SRU, /* system register unit (601/603 style) */
80 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
81 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
82 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
83 PPC_UNIT_FPU, /* floating point unit */
84 PPC_UNIT_LSU, /* load/store unit */
85 PPC_UNIT_BPU, /* branch unit */
89 /* Structure to hold timing information on a per instruction basis */
91 ppc_function_unit first_unit; /* first functional unit this insn could use */
92 ppc_function_unit last_unit; /* last functional unit this insn could use */
93 unsigned16 issue; /* # cycles before function unit can process other insns */
94 unsigned16 done; /* # cycles before insn is done */
95 unsigned32 flags; /* flag bits */
99 #define PPC_LOAD 0x00000001 /* insn is a load */
100 #define PPC_STORE 0x00000002 /* insn is a store */
101 #define PPC_SERIALIZE 0x00000004 /* insn forces serialization */
103 /* Structure to hold the current state information for the simulated CPU model */
105 const char *name; /* model name */
106 const model_time *timing; /* timing information */
107 unsigned nr_branches; /* # branches */
108 unsigned nr_branches_fallthrough; /* # conditional branches that fell through */
109 unsigned nr_branch_predict_trues; /* # branches predicted correctly */
110 unsigned nr_branch_predict_falses; /* # branches predicted incorrectly */
111 unsigned nr_units[nr_ppc_function_units]; /* function unit counts */
112 unsigned16 busy[nr_ppc_function_units]; /* how long until free */
115 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
116 "unknown functional unit instruction",
117 "integer functional unit instruction",
118 "system register functional unit instruction",
119 "1st single cycle integer functional unit instruction",
120 "2nd single cycle integer functional unit instruction",
121 "multiple cycle integer functional unit instruction",
122 "floating point functional unit instruction",
123 "load/store functional unit instruction",
124 "branch functional unit instruction",
127 model_data *::model-function::model_create:cpu *processor
128 if (CURRENT_MODEL == MODEL_NONE) {
129 error("Must define a CPU model");
130 return (model_data *)0;
133 model_data *model_ptr = ZALLOC(model_data);
134 model_ptr->name = model_name[CURRENT_MODEL];
135 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
139 void::model-function::model_init:cpu *processor, model_data *model_ptr
141 void::model-function::model_halt:cpu *processor, model_data *model_ptr
143 void::model-function::model_issue:itable_index index, cpu *processor, model_data *model_ptr, unsigned_word cia
144 model_ptr->nr_units[ (int)model_ptr->timing[ (int)index ].first_unit ]++;
146 /* Assume that any instruction we don't know about is illegal for this
148 if (model_ptr->timing[(int)index].first_unit == PPC_UNIT_BAD)
149 program_interrupt(processor, cia,
150 illegal_instruction_program_interrupt);
152 model_print *::model-function::model_mon_info:model_data *model_ptr
157 head = tail = ZALLOC(model_print);
158 tail->count = model_ptr->nr_branches;
159 tail->name = "branch";
160 tail->suffix_plural = "es";
161 tail->suffix_singular = "";
163 if (model_ptr->nr_branches_fallthrough) {
164 tail->next = ZALLOC(model_print);
166 tail->count = model_ptr->nr_branches_fallthrough;
167 tail->name = "conditional branch";
168 tail->suffix_plural = "es fell through";
169 tail->suffix_singular = " fell through";
172 if (model_ptr->nr_branch_predict_trues) {
173 tail->next = ZALLOC(model_print);
175 tail->count = model_ptr->nr_branch_predict_trues;
176 tail->name = "successful branch prediction";
177 tail->suffix_plural = "s";
178 tail->suffix_singular = "";
181 if (model_ptr->nr_branch_predict_falses) {
182 tail->next = ZALLOC(model_print);
184 tail->count = model_ptr->nr_branch_predict_falses;
185 tail->name = "unsuccessful branch prediction";
186 tail->suffix_plural = "s";
187 tail->suffix_singular = "";
190 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
191 if (model_ptr->nr_units[i]) {
192 tail->next = ZALLOC(model_print);
194 tail->count = model_ptr->nr_units[i];
195 tail->name = ppc_function_unit_name[i];
196 tail->suffix_plural = "s";
197 tail->suffix_singular = "";
201 tail->next = (model_print *)0;
204 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
213 void::model-function::model_branches:model_data *model_ptr, int failed
215 model_ptr->nr_branches_fallthrough++;
217 model_ptr->nr_branches++;
219 void::model-function::model_branch_predict:model_data *model_ptr, int success
221 model_ptr->nr_branch_predict_trues++;
223 model_ptr->nr_branch_predict_falses++;
225 # The following (illegal) instruction is `known' by gen and is
226 # called when ever an illegal instruction is encountered
228 program_interrupt(processor, cia,
229 illegal_instruction_program_interrupt);
233 # The following (floating point unavailable) instruction is `known' by gen
234 # and is called when ever an a floating point instruction is to be
235 # executed but floating point is make unavailable by the MSR
236 ::internal::floating_point_unavailable
237 floating_point_unavailable_interrupt(processor, cia);
242 # Floating point support functions
245 # Convert 32bit single to 64bit double
246 unsigned64::function::DOUBLE:unsigned32 WORD
248 if (EXTRACTED32(WORD, 1, 8) > 0
249 && EXTRACTED32(WORD, 1, 8) < 255) {
250 /* normalized operand */
251 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
252 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
253 | INSERTED64(not_word_1_1, 2, 2)
254 | INSERTED64(not_word_1_1, 3, 3)
255 | INSERTED64(not_word_1_1, 4, 4)
256 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
258 else if (EXTRACTED32(WORD, 1, 8) == 0
259 && EXTRACTED32(WORD, 9, 31) != 0) {
260 /* denormalized operand */
261 int sign = EXTRACTED32(WORD, 0, 0);
263 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
264 /* normalize the operand */
265 while (MASKED64(frac, 0, 0) == 0) {
269 FRT = (INSERTED64(sign, 0, 0)
270 | INSERTED64(exp + 1023, 1, 11)
271 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
273 else if (EXTRACTED32(WORD, 1, 8) == 255
274 || EXTRACTED32(WORD, 1, 31) == 0) {
275 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
276 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
277 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
278 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
279 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
282 error("DOUBLE - unknown case\n");
287 # Convert 64bit single to 32bit double
288 unsigned32::function::SINGLE:unsigned64 FRS
290 if (EXTRACTED64(FRS, 1, 11) > 896
291 || EXTRACTED64(FRS, 1, 63) == 0) {
292 /* no denormalization required (includes Zero/Infinity/NaN) */
293 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
294 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
296 else if (874 <= EXTRACTED64(FRS, 1, 11)
297 && EXTRACTED64(FRS, 1, 11) <= 896) {
298 /* denormalization required */
299 int sign = EXTRACTED64(FRS, 0, 0);
300 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
301 unsigned64 frac = (BIT64(0)
302 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
303 /* denormalize the operand */
305 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
308 WORD = (INSERTED32(sign, 0, 0)
309 | INSERTED32(0x00, 1, 8)
310 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
313 WORD = 0x0; /* ??? */
318 # round 64bit double to 64bit but single
319 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
320 /* comparisons ignore u bits */
323 int lsb = EXTRACTED64(*frac_grx, 23, 23);
324 int gbit = EXTRACTED64(*frac_grx, 24, 24);
325 int rbit = EXTRACTED64(*frac_grx, 25, 25);
326 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
327 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
328 if (lsb == 1 && gbit == 1) inc = 1;
329 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
330 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
332 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
333 if (sign == 0 && gbit == 1) inc = 1;
334 if (sign == 0 && rbit == 1) inc = 1;
335 if (sign == 0 && xbit == 1) inc = 1;
337 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
338 if (sign == 1 && gbit == 1) inc = 1;
339 if (sign == 1 && rbit == 1) inc = 1;
340 if (sign == 1 && xbit == 1) inc = 1;
342 /* work out addition in low 25 bits of out */
343 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
344 *frac_grx = INSERTED64(out, 0, 23);
345 if (out & BIT64(64 - 23 - 1 - 1)) {
346 *frac_grx = (BIT64(0) |
347 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
350 /* frac_grx[24:52] = 0 already */
352 FPSCR_SET_FI(gbit || rbit || xbit);
356 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
358 if (round_mode == fpscr_rn_round_to_nearest) {
359 if (*frac64 == 1 && gbit == 1) inc = 1;
360 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
361 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
363 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
364 if (sign == 0 && gbit == 1) inc = 1;
365 if (sign == 0 && rbit == 1) inc = 1;
366 if (sign == 0 && xbit == 1) inc = 1;
368 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
369 if (sign == 1 && gbit == 1) inc = 1;
370 if (sign == 1 && rbit == 1) inc = 1;
371 if (sign == 1 && xbit == 1) inc = 1;
373 /* frac[0:64] = frac[0:64} + inc */
374 *frac += (*frac64 && inc ? 1 : 0);
375 *frac64 = (*frac64 + inc) & 0x1;
377 FPSCR_SET_FI(gbit | rbit | xbit);
380 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
383 int lsb = EXTRACTED64(*frac, 52, 52);
384 int gbit = EXTRACTED64(*frac, 53, 53);
385 int rbit = EXTRACTED64(*frac, 54, 54);
386 int xbit = EXTRACTED64(*frac, 55, 55);
387 if (round_mode == fpscr_rn_round_to_nearest) {
388 if (lsb == 1 && gbit == 1) inc = 1;
389 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
390 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
392 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
393 if (sign == 0 && gbit == 1) inc = 1;
394 if (sign == 0 && rbit == 1) inc = 1;
395 if (sign == 0 && xbit == 1) inc = 1;
397 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
398 if (sign == 1 && gbit == 1) inc = 1;
399 if (sign == 1 && rbit == 1) inc = 1;
400 if (sign == 1 && xbit == 1) inc = 1;
402 /* frac//carry_out = frac + inc */
403 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
404 carry_out = EXTRACTED64(*frac, 0, 0);
406 if (carry_out == 1) *exp = *exp + 1;
408 FPSCR_SET_FI(gbit | rbit | xbit);
409 FPSCR_SET_XX(FPSCR & fpscr_fi);
412 # conversion of FP to integer
413 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
421 int sign = EXTRACTED64(frb, 0, 0);
422 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
423 goto Infinity_Operand;
424 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
426 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
428 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
429 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
430 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
431 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
432 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
435 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
436 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
439 gbit = 0, rbit = 0, xbit = 0;
440 for (i = 1; i <= 63 - exp; i++) {
444 frac64 = EXTRACTED64(frac, 63, 63);
445 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
447 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
448 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
451 frac += (frac64 ? 1 : 0);
452 frac64 = (frac64 + 1) & 0x1;
454 if (tgt_precision == 32 /* can ignore frac64 in compare */
455 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
457 if (tgt_precision == 64 /* can ignore frac64 in compare */
458 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
460 if (tgt_precision == 32 /* can ignore frac64 in compare */
461 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
463 if (tgt_precision == 64 /* can ignore frac64 in compare */
464 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
466 FPSCR_SET_XX(FPSCR & fpscr_fi);
467 if (tgt_precision == 32)
468 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
469 if (tgt_precision == 64)
470 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
471 /*FPSCR[fprf] = undefined */
477 FPSCR_OR_VX(fpscr_vxcvi);
478 if ((FPSCR & fpscr_ve) == 0) {
479 if (tgt_precision == 32) {
480 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
481 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
484 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
485 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
487 /* FPSCR[FPRF] = undefined */
494 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
495 if ((FPSCR & fpscr_ve) == 0) {
496 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
497 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
498 /* FPSCR[fprf] = undefined */
505 FPSCR_OR_VX(fpscr_vxcvi);
506 if ((FPSCR & fpscr_ve) == 0) {
507 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
508 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
509 /* FPSCR[fprf] = undefined */
516 FPSCR_OR_VX(fpscr_vxcvi);
517 if ((FPSCR & fpscr_ve) == 0) {
518 if (tgt_precision == 32) {
519 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
520 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
523 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
524 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
526 /* FPSCR[fprf] = undefined */
532 # extract out raw fields of a FP number
533 int::function::sign:unsigned64 FRS
534 return (MASKED64(FRS, 0, 0)
537 int::function::biased_exp:unsigned64 frs, int single
539 return EXTRACTED64(frs, 1, 8);
541 return EXTRACTED64(frs, 1, 11);
542 unsigned64::function::fraction:unsigned64 frs, int single
544 return EXTRACTED64(frs, 9, 31);
546 return EXTRACTED64(frs, 12, 63);
548 # a number?, each of the below return +1 or -1 (based on sign bit)
550 int::function::is_nor:unsigned64 frs, int single
551 int exp = biased_exp(frs, single);
553 && exp <= (single ? 254 : 2046));
554 int::function::is_zero:unsigned64 FRS
555 return (MASKED64(FRS, 1, 63) == 0
558 int::function::is_den:unsigned64 frs, int single
559 int exp = biased_exp(frs, single);
560 unsigned64 frac = fraction(frs, single);
561 return (exp == 0 && frac != 0
564 int::function::is_inf:unsigned64 frs, int single
565 int exp = biased_exp(frs, single);
566 int frac = fraction(frs, single);
567 return (exp == (single ? 255 : 2047) && frac == 0
570 int::function::is_NaN:unsigned64 frs, int single
571 int exp = biased_exp(frs, single);
572 int frac = fraction(frs, single);
573 return (exp == (single ? 255 : 2047) && frac != 0
576 int::function::is_SNaN:unsigned64 frs, int single
577 return (is_NaN(frs, single)
578 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
581 int::function::is_QNaN:unsigned64 frs, int single
582 return (is_NaN(frs, single) && !is_SNaN(frs, single));
583 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
584 return *(double*)fra < *(double*)frb;
585 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
586 return *(double*)fra > *(double*)frb;
587 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
588 return *(double*)fra == *(double*)frb;
591 # which quiet nan should become the result
592 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
594 if (is_NaN(fra, single))
596 else if (is_NaN(frb, single))
597 if (instruction_is_frsp)
598 frt = MASKED64(frb, 0, 34);
601 else if (is_NaN(frc, single))
603 else if (generate_qnan)
604 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
606 error("select_qnan - default reached\n");
610 # detect invalid operation
611 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
613 if ((check & fpscr_vxsnan)
614 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
615 FPSCR_OR_VX(fpscr_vxsnan);
618 if ((check & fpscr_vxisi)
619 && (is_inf(fra, single) && is_inf(frb, single))
620 && ((negate && sign(fra) != sign(frb))
621 || (!negate && sign(fra) == sign(frb)))) {
622 /*FIXME: don't handle inf-inf VS inf+-inf */
623 FPSCR_OR_VX(fpscr_vxisi);
626 if ((check & fpscr_vxidi)
627 && (is_inf(fra, single) && is_inf(frb, single))) {
628 FPSCR_OR_VX(fpscr_vxidi);
631 if ((check & fpscr_vxzdz)
632 && (is_zero(fra) && is_zero(frb))) {
633 FPSCR_OR_VX(fpscr_vxzdz);
636 if ((check & fpscr_vximz)
637 && (is_zero(fra) && is_inf(frb, single))) {
638 FPSCR_OR_VX(fpscr_vximz);
641 if ((check & fpscr_vxvc)
642 && (is_NaN(fra, single) || is_NaN(frb, single))) {
643 FPSCR_OR_VX(fpscr_vxvc);
646 if ((check & fpscr_vxsoft)) {
647 FPSCR_OR_VX(fpscr_vxsoft);
650 if ((check & fpscr_vxsqrt)
652 FPSCR_OR_VX(fpscr_vxsqrt);
655 /* if ((check && fpscr_vxcvi) {
656 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
657 FPSCR_OR_VX(fpscr_vxcvi);
667 # handle case of invalid operation
668 void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int instruction_is_convert_to_64bit, int instruction_is_convert_to_32bit, int single
669 if (FPSCR & fpscr_ve) {
670 /* invalid operation exception enabled */
674 /* fpscr_FPRF unchanged */
677 /* invalid operation exception disabled */
678 if (instruction_is_convert_to_64bit) {
681 else if (instruction_is_convert_to_32bit) {
684 else { /* arrith, frsp */
685 *frt = select_qnan(fra, frb, frc,
686 instruction_is_frsp, 0/*generate*/, single);
689 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
697 # I.2.4.1 Branch Instructions
699 0.18,6.LI,30.AA,31.LK:I:t::Branch
700 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
701 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
702 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
703 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
704 if (AA) NIA = IEA(EXTS(LI_0b00));
705 else NIA = IEA(CIA + EXTS(LI_0b00));
706 if (LK) LR = (spreg)CIA+4;
707 model_branches(cpu_model(processor), 1);
709 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
710 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
711 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
712 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
713 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
714 int M, ctr_ok, cond_ok, succeed;
715 if (is_64bit_implementation && is_64bit_mode) M = 0;
717 if (!BO{2}) CTR = CTR - 1;
718 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
719 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
720 if (ctr_ok && cond_ok) {
721 if (AA) NIA = IEA(EXTS(BD_0b00));
722 else NIA = IEA(CIA + EXTS(BD_0b00));
727 if (LK) LR = (spreg)IEA(CIA + 4);
728 model_branches(cpu_model(processor), succeed);
731 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
732 reverse = EXTS(BD_0b00) < 0;
733 } else { /* branch prediction bit not set */
734 reverse = EXTS(BD_0b00) >= 0;
736 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
739 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
740 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
741 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
742 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
743 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
744 int M, ctr_ok, cond_ok, succeed;
745 if (is_64bit_implementation && is_64bit_mode) M = 0;
747 if (!BO{2}) CTR = CTR - 1;
748 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
749 cond_ok = BO{0} || (CR{BI} == BO{1});
750 if (ctr_ok && cond_ok) {
756 if (LK) LR = (spreg)IEA(CIA + 4);
757 model_branches(cpu_model(processor), succeed);
759 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
761 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
762 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
763 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
764 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
765 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
766 int cond_ok, succeed;
767 cond_ok = BO{0} || (CR{BI} == BO{1});
774 if (LK) LR = (spreg)IEA(CIA + 4);
775 model_branches(cpu_model(processor), succeed);
777 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
780 # I.2.4.2 System Call Instruction
782 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
783 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
784 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
785 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
786 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, PPC_SERIALIZE
787 system_call_interrupt(processor, cia);
790 # I.2.4.3 Condition Register Logical Instructions
792 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
793 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
794 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
795 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
796 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
797 BLIT32(CR, BT, CR{BA} && CR{BB});
799 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
800 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
801 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
802 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
803 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
804 BLIT32(CR, BT, CR{BA} || CR{BB});
806 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
807 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
808 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
809 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
810 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
811 BLIT32(CR, BT, CR{BA} != CR{BB});
813 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
814 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
815 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
816 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
817 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
818 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
820 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
821 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
822 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
823 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
824 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
825 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
827 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
828 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
829 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
830 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
831 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
832 BLIT32(CR, BT, CR{BA} == CR{BB});
834 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
835 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
836 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
837 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
838 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
839 BLIT32(CR, BT, CR{BA} && !CR{BB});
841 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
842 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
843 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
844 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
845 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
846 BLIT32(CR, BT, CR{BA} || !CR{BB});
849 # I.2.4.4 Condition Register Field Instruction
851 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
852 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
853 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
854 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
855 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
856 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
860 # I.3.3.2 Fixed-Point Load Instructions
863 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
864 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
865 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
866 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
867 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
873 *rT = MEM(unsigned, EA, 1);
875 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
876 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
877 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
878 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
879 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
885 *rT = MEM(unsigned, EA, 1);
887 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
888 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
889 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
890 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
891 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
893 if (RA == 0 || RA == RT)
894 program_interrupt(processor, cia,
895 illegal_instruction_program_interrupt);
897 *rT = MEM(unsigned, EA, 1);
900 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
901 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
902 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
903 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
904 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
906 if (RA == 0 || RA == RT)
907 program_interrupt(processor, cia,
908 illegal_instruction_program_interrupt);
910 *rT = MEM(unsigned, EA, 1);
913 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
914 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
915 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
916 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
917 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
923 *rT = MEM(unsigned, EA, 2);
925 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
926 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
927 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
928 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
929 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
935 *rT = MEM(unsigned, EA, 2);
936 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
937 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
938 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
939 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
940 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
942 if (RA == 0 || RA == RT)
943 program_interrupt(processor, cia,
944 illegal_instruction_program_interrupt);
946 *rT = MEM(unsigned, EA, 2);
949 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
950 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
951 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
952 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
953 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
955 if (RA == 0 || RA == RT)
956 program_interrupt(processor, cia,
957 illegal_instruction_program_interrupt);
959 *rT = MEM(unsigned, EA, 2);
962 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
963 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
964 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
965 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
966 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
972 *rT = MEM(signed, EA, 2);
974 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
975 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
976 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
977 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
978 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
984 *rT = MEM(signed, EA, 2);
986 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
987 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
988 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
989 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
990 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
992 if (RA == 0 || RA == RT)
993 program_interrupt(processor, cia,
994 illegal_instruction_program_interrupt);
996 *rT = MEM(signed, EA, 2);
998 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
999 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1000 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1001 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1002 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1004 if (RA == 0 || RA == RT)
1005 program_interrupt(processor, cia,
1006 illegal_instruction_program_interrupt);
1008 *rT = MEM(signed, EA, 2);
1011 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1012 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1013 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1014 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1015 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1021 *rT = MEM(unsigned, EA, 4);
1023 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1024 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1025 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1026 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1027 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1033 *rT = MEM(unsigned, EA, 4);
1035 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1036 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1037 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1038 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1039 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1041 if (RA == 0 || RA == RT)
1042 program_interrupt(processor, cia,
1043 illegal_instruction_program_interrupt);
1045 *rT = MEM(unsigned, EA, 4);
1048 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1049 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1050 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1051 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1052 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1054 if (RA == 0 || RA == RT)
1055 program_interrupt(processor, cia,
1056 illegal_instruction_program_interrupt);
1058 *rT = MEM(unsigned, EA, 4);
1061 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1064 # if (RA == 0) b = 0;
1066 # EA = b + EXTS(DS_0b00);
1067 # *rT = MEM(signed, EA, 4);
1069 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1072 # if (RA == 0) b = 0;
1075 # *rT = MEM(signed, EA, 4);
1077 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1079 # if (RA == 0 || RA == RT)
1080 # program_interrupt(processor, cia
1081 # illegal_instruction_program_interrupt);
1083 # *rT = MEM(signed, EA, 4);
1086 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1089 # if (RA == 0) b = 0;
1091 # EA = b + EXTS(DS_0b00);
1092 # *rT = MEM(unsigned, EA, 8);
1094 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1097 # if (RA == 0) b = 0;
1100 # *rT = MEM(unsigned, EA, 8);
1102 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1104 # if (RA == 0 || RA == RT)
1105 # program_interrupt(processor, cia
1106 # illegal_instruction_program_interrupt);
1107 # EA = *rA + EXTS(DS_0b00);
1108 # *rT = MEM(unsigned, EA, 8);
1111 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1113 # if (RA == 0 || RA == RT)
1114 # program_interrupt(processor, cia
1115 # illegal_instruction_program_interrupt);
1117 # *rT = MEM(unsigned, EA, 8);
1123 # I.3.3.3 Fixed-Point Store Instructions
1126 0.38,6.RS,11.RA,16.D:D:::Store Byte
1127 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1128 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1129 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1130 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1138 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1139 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1140 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1141 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1142 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1150 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1151 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1152 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1153 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1154 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1157 program_interrupt(processor, cia,
1158 illegal_instruction_program_interrupt);
1163 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1164 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1165 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1166 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1167 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1170 program_interrupt(processor, cia,
1171 illegal_instruction_program_interrupt);
1176 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1177 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1178 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1179 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1180 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1188 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1189 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1190 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1191 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1192 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1200 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1201 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1202 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1203 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1204 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1207 program_interrupt(processor, cia,
1208 illegal_instruction_program_interrupt);
1213 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1214 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1215 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1216 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1217 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1220 program_interrupt(processor, cia,
1221 illegal_instruction_program_interrupt);
1226 0.36,6.RS,11.RA,16.D:D:::Store Word
1227 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1228 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1229 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1230 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1238 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
1239 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1240 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1241 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1242 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1250 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
1251 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1252 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1253 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1254 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1257 program_interrupt(processor, cia,
1258 illegal_instruction_program_interrupt);
1263 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
1264 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1265 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1266 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1267 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1270 program_interrupt(processor, cia,
1271 illegal_instruction_program_interrupt);
1276 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
1279 # if (RA == 0) b = 0;
1281 # EA = b + EXTS(DS_0b00);
1282 # STORE(EA, 8, *rS);
1283 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
1286 # if (RA == 0) b = 0;
1289 # STORE(EA, 8, *rS);
1290 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
1293 # program_interrupt(processor, cia
1294 # illegal_instruction_program_interrupt);
1295 # EA = *rA + EXTS(DS_0b00);
1296 # STORE(EA, 8, *rS);
1298 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
1301 # program_interrupt(processor, cia
1302 # illegal_instruction_program_interrupt);
1304 # STORE(EA, 8, *rS);
1309 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
1312 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
1313 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1314 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1315 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1316 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1322 *rT = SWAP_2(MEM(unsigned, EA, 2));
1324 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
1325 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1326 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1327 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1328 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1334 *rT = SWAP_4(MEM(unsigned, EA, 4));
1336 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
1337 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1338 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1339 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1340 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1346 STORE(EA, 2, SWAP_2(*rS));
1348 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
1349 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1350 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1351 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1352 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1358 STORE(EA, 4, SWAP_4(*rS));
1362 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
1365 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
1367 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
1371 # I.3.3.6 Fixed-Point Move Assist Instructions
1374 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
1376 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
1378 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
1380 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
1384 # I.3.3.7 Storage Synchronization Instructions
1386 # HACK: Rather than monitor addresses looking for a reason
1387 # to cancel a reservation. This code instead keeps
1388 # a copy of the data read from memory. Before performing
1389 # a store, the memory area is checked to see if it has
1391 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
1392 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1393 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
1394 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
1395 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
1402 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1403 RESERVE_DATA = MEM(unsigned, EA, 4);
1406 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
1413 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1414 RESERVE_DATA = MEM(unsigned, EA, 8);
1417 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
1418 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1419 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
1420 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
1421 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
1428 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1429 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
1431 CR_SET_XER_SO(0, cr_i_zero);
1434 /* ment to randomly to store, we never do! */
1435 CR_SET_XER_SO(0, 0);
1440 CR_SET_XER_SO(0, 0);
1442 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
1449 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1450 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
1452 CR_SET_XER_SO(0, cr_i_zero);
1455 /* ment to randomly to store, we never do */
1456 CR_SET_XER_SO(0, 0);
1461 CR_SET_XER_SO(0, 0);
1464 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
1465 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
1466 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, PPC_SERIALIZE
1467 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, PPC_SERIALIZE
1468 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
1473 # I.3.3.9 Fixed-Point Arithmetic Instructions
1476 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
1477 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1478 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1479 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1480 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1481 if (RA_is_0) *rT = EXTS(SI);
1482 else *rT = *rA + EXTS(SI);
1484 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
1485 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1486 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1487 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1488 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1489 if (RA_is_0) *rT = EXTS(SI) << 16;
1490 else *rT = *rA + (EXTS(SI) << 16);
1492 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
1493 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1494 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1495 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1496 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1499 ALU_END(*rT, 0/*CA*/, OE, Rc);
1501 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
1502 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1503 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1504 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1505 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1510 ALU_END(*rT, 0/*CA*/, OE, Rc);
1512 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
1513 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1514 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1515 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1516 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1519 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1521 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
1522 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1523 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1524 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1525 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1528 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
1530 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
1531 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1532 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1533 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1534 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1539 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1541 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
1542 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1543 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1544 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1545 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1548 ALU_END(*rT, 1/*CA*/, OE, Rc);
1550 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
1551 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1552 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1553 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1554 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1555 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
1560 ALU_END(*rT, 1/*CA*/, OE, Rc);
1562 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
1563 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1564 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1565 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1566 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1570 ALU_END(*rT, 1/*CA*/, OE, Rc);
1572 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
1573 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1574 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1575 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1576 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1581 ALU_END(*rT, 1/*CA*/, OE, Rc);
1583 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
1584 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1585 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1586 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1587 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1591 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1593 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
1594 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1595 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1596 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1597 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1602 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1604 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
1605 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1606 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1607 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1608 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1611 ALU_END(*rT, 1/*CA*/, OE, Rc);
1613 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
1614 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1615 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1616 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1617 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1621 ALU_END(*rT, 1/*CA*/, OE, Rc);
1623 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
1624 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1625 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1626 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1627 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1631 ALU_END(*rT,0/*CA*/,OE,Rc);
1633 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
1634 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1635 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
1636 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
1637 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
1638 signed_word prod = *rA * EXTS(SI);
1641 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
1643 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
1644 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1645 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1646 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1647 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
1648 signed64 a = (signed32)(*rA);
1649 signed64 b = (signed32)(*rB);
1650 signed64 prod = a * b;
1651 signed_word t = prod;
1653 if (t != prod && OE)
1654 XER |= (xer_overflow | xer_summary_overflow);
1655 CR0_COMPARE(t, 0, Rc);
1657 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
1659 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
1660 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1661 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1662 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1663 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
1664 signed64 a = (signed32)(*rA);
1665 signed64 b = (signed32)(*rB);
1666 signed64 prod = a * b;
1667 signed_word t = EXTRACTED64(prod, 0, 31);
1669 CR0_COMPARE(t, 0, Rc);
1671 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
1673 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
1674 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
1675 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
1676 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
1677 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
1678 unsigned64 a = (unsigned32)(*rA);
1679 unsigned64 b = (unsigned32)(*rB);
1680 unsigned64 prod = a * b;
1681 signed_word t = EXTRACTED64(prod, 0, 31);
1683 CR0_COMPARE(t, 0, Rc);
1685 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
1687 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
1688 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
1689 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
1690 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
1691 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
1692 signed64 dividend = (signed32)(*rA);
1693 signed64 divisor = (signed32)(*rB);
1694 if (divisor == 0 /* nb 0x8000..0 is sign extended */
1695 || (dividend == 0x80000000 && divisor == -1)) {
1697 XER |= (xer_overflow | xer_summary_overflow);
1698 CR0_COMPARE(0, 0, Rc);
1701 signed64 quotent = dividend / divisor;
1703 CR0_COMPARE((signed_word)quotent, 0, Rc);
1705 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
1707 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
1708 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
1709 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
1710 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
1711 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
1712 unsigned64 dividend = (unsigned32)(*rA);
1713 unsigned64 divisor = (unsigned32)(*rB);
1716 XER |= (xer_overflow | xer_summary_overflow);
1717 CR0_COMPARE(0, 0, Rc);
1720 unsigned64 quotent = dividend / divisor;
1722 CR0_COMPARE((signed_word)quotent, 0, Rc);
1727 # I.3.3.10 Fixed-Point Compare Instructions
1730 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
1731 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1732 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1733 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1734 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1735 if (!is_64bit_mode && L)
1736 program_interrupt(processor, cia,
1737 illegal_instruction_program_interrupt);
1740 signed_word b = EXTS(SI);
1745 CR_COMPARE(BF, a, b);
1748 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
1749 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1750 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1751 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1752 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1753 if (!is_64bit_mode && L)
1754 program_interrupt(processor, cia,
1755 illegal_instruction_program_interrupt);
1767 CR_COMPARE(BF, a, b);
1770 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
1771 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1772 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1773 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1774 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1775 if (!is_64bit_mode && L)
1776 program_interrupt(processor, cia,
1777 illegal_instruction_program_interrupt);
1780 unsigned_word b = UI;
1782 a = MASKED(*rA, 32, 63);
1785 CR_COMPARE(BF, a, b);
1788 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
1789 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1790 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1791 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1792 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1793 if (!is_64bit_mode && L)
1794 program_interrupt(processor, cia,
1795 illegal_instruction_program_interrupt);
1800 a = MASKED(*rA, 32, 63);
1801 b = MASKED(*rB, 32, 63);
1807 CR_COMPARE(BF, a, b);
1812 # I.3.3.11 Fixed-Point Trap Instructions
1815 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
1817 program_interrupt(processor, cia,
1818 illegal_instruction_program_interrupt);
1820 signed_word a = *rA;
1821 signed_word b = EXTS(SI);
1822 if ((a < b && TO{0})
1824 || (a == b && TO{2})
1825 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1826 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1828 program_interrupt(processor, cia,
1829 trap_program_interrupt);
1832 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
1833 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1834 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1835 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1836 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1837 signed_word a = EXTENDED(*rA);
1838 signed_word b = EXTS(SI);
1839 if ((a < b && TO{0})
1841 || (a == b && TO{2})
1842 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1843 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1845 program_interrupt(processor, cia,
1846 trap_program_interrupt);
1848 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
1850 program_interrupt(processor, cia,
1851 illegal_instruction_program_interrupt);
1853 signed_word a = *rA;
1854 signed_word b = *rB;
1855 if ((a < b && TO{0})
1857 || (a == b && TO{2})
1858 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1859 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1861 program_interrupt(processor, cia,
1862 trap_program_interrupt);
1865 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
1866 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1867 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1868 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1869 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1870 signed_word a = EXTENDED(*rA);
1871 signed_word b = EXTENDED(*rB);
1872 if (TO == 12 && rA == rB) {
1873 ITRACE(trace_breakpoint, ("breakpoint\n"));
1874 cpu_halt(processor, cia, was_trap, 0);
1876 else if ((a < b && TO{0})
1878 || (a == b && TO{2})
1879 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1880 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1882 program_interrupt(processor, cia,
1883 trap_program_interrupt);
1886 # I.3.3.12 Fixed-Point Logical Instructions
1889 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
1890 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1891 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1892 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1893 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1895 CR0_COMPARE(*rA, 0, 1/*Rc*/);
1897 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
1898 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1899 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1900 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1901 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1902 *rA = *rS & (UI << 16);
1903 CR0_COMPARE(*rA, 0, 1/*Rc*/);
1905 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
1906 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1907 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1908 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1909 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1912 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
1913 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1914 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1915 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1916 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1917 *rA = *rS | (UI << 16);
1919 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
1920 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1921 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1922 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1923 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1926 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
1927 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1928 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1929 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1930 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1931 *rA = *rS ^ (UI << 16);
1933 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
1934 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1935 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1936 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1937 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1939 CR0_COMPARE(*rA, 0, Rc);
1941 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
1942 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1943 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1944 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1945 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1947 CR0_COMPARE(*rA, 0, Rc);
1949 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
1950 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1951 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1952 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1953 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1955 CR0_COMPARE(*rA, 0, Rc);
1957 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
1958 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1959 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1960 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1961 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1963 CR0_COMPARE(*rA, 0, Rc);
1965 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
1966 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1967 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1968 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1969 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1971 CR0_COMPARE(*rA, 0, Rc);
1973 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
1974 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1975 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1976 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1977 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1978 # *rA = ~(*rS ^ *rB); /* A === B */
1979 # CR0_COMPARE(*rA, 0, Rc);
1981 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
1982 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1983 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1984 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1985 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1987 CR0_COMPARE(*rA, 0, Rc);
1988 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
1989 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1990 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1991 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1992 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1994 CR0_COMPARE(*rA, 0, Rc);
1996 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
1997 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1998 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1999 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2000 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2001 *rA = (signed_word)(signed8)*rS;
2002 CR0_COMPARE(*rA, 0, Rc);
2004 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
2005 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2006 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2007 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2008 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2009 *rA = (signed_word)(signed16)*rS;
2010 CR0_COMPARE(*rA, 0, Rc);
2012 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2013 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2014 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2015 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2016 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2017 # *rA = (signed_word)(signed32)*rS;
2018 # CR0_COMPARE(*rA, 0, Rc);
2020 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2022 # unsigned64 mask = BIT64(0);
2023 # unsigned64 source = *rS;
2024 # while (!(source & mask) && mask != 0) {
2029 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2031 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
2032 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2033 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2034 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2035 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2037 unsigned32 mask = BIT32(0);
2038 unsigned32 source = *rS;
2039 while (!(source & mask) && mask != 0) {
2044 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2048 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2051 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
2052 # long n = (sh_5 << 4) | sh_0_4;
2053 # unsigned_word r = ROTL64(*rS, n);
2054 # long b = (mb_5 << 4) | mb_0_4;
2055 # unsigned_word m = MASK(b, 63);
2056 # signed_word result = r & m;
2058 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2060 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
2061 # long n = (sh_5 << 4) | sh_0_4;
2062 # unsigned_word r = ROTL64(*rS, n);
2063 # long e = (me_5 << 4) | me_0_4;
2064 # unsigned_word m = MASK(0, e);
2065 # signed_word result = r & m;
2067 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2069 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
2070 # long n = (sh_5 << 4) | sh_0_4;
2071 # unsigned_word r = ROTL64(*rS, n);
2072 # long b = (mb_5 << 4) | mb_0_4;
2073 # unsigned_word m = MASK(0, (64-n));
2074 # signed_word result = r & m;
2076 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2078 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2079 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2080 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2081 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2082 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2085 unsigned32 r = ROTL32(s, n);
2086 unsigned32 m = MASK(MB+32, ME+32);
2087 signed_word result = r & m;
2089 CR0_COMPARE(result, 0, Rc);
2091 ("n=%d, s=0x%x, r=0x%x, m=0x%x, result=0x%x, cr=0x%x\n",
2092 n, s, r, m, result, CR));
2094 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2095 # long n = MASKED(*rB, 58, 63);
2096 # unsigned_word r = ROTL64(*rS, n);
2097 # long b = (mb_5 << 4) | mb_0_4;
2098 # unsigned_word m = MASK(b, 63);
2099 # signed_word result = r & m;
2101 # CR0_COMPARE(result, 0, Rc);
2103 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2104 # long n = MASKED(*rB, 58, 63);
2105 # unsigned_word r = ROTL64(*rS, n);
2106 # long e = (me_5 << 4) | me_0_4;
2107 # unsigned_word m = MASK(0, e);
2108 # signed_word result = r & m;
2110 # CR0_COMPARE(result, 0, Rc);
2112 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2113 # long n = MASKED(*rB, 59, 63);
2114 # unsigned32 r = ROTL32(*rS, n);
2115 # unsigned32 m = MASK(MB+32, ME+32);
2116 # signed_word result = r & m;
2118 # CR0_COMPARE(result, 0, Rc);
2120 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
2121 # long n = (sh_5 << 4) | sh_0_4;
2122 # unsigned_word r = ROTL64(*rS, n);
2123 # long b = (mb_5 << 4) | mb_0_4;
2124 # unsigned_word m = MASK(b, (64-n));
2125 # signed_word result = (r & m) | (*rA & ~m)
2127 # CR0_COMPARE(result, 0, Rc);
2129 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2130 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2131 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2132 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2133 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2135 unsigned32 r = ROTL32(*rS, n);
2136 unsigned32 m = MASK(MB+32, ME+32);
2137 signed_word result = (r & m) | (*rA & ~m);
2139 ITRACE(trace_alu, (": n=%d *rS=0x%x r=0x%x m=0x%x result=0x%x\n",
2140 n, *rS, r, m, result));
2141 CR0_COMPARE(result, 0, Rc);
2144 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2146 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2147 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2148 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2149 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2150 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2151 int n = MASKED(*rB, 59, 63);
2152 unsigned32 source = *rS;
2153 signed_word shifted;
2155 shifted = (source << n);
2159 CR0_COMPARE(shifted, 0, Rc);
2161 ("n=%d, source=0x%x, shifted=0x%x\n",
2162 n, source, shifted));
2164 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
2166 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
2167 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2168 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2169 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2170 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2171 int n = MASKED(*rB, 59, 63);
2172 unsigned32 source = *rS;
2173 signed_word shifted;
2175 shifted = (source >> n);
2179 CR0_COMPARE(shifted, 0, Rc);
2181 ("n=%d, source=0x%x, shifted=0x%x\n",
2182 n, source, shifted));
2184 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
2186 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
2187 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2188 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2189 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2190 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2192 signed_word r = ROTL32(*rS, /*64*/32-n);
2193 signed_word m = MASK(n+32, 63);
2194 int S = MASKED(*rS, 32, 32);
2195 signed_word shifted = (r & m) | (S ? ~m : 0);
2197 if (S && ((r & ~m) & MASK(32, 63)) != 0)
2201 CR0_COMPARE(shifted, 0, Rc);
2203 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
2205 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
2206 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2207 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2208 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2209 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2210 int n = MASKED(*rB, 58, 63);
2211 int shift = (n >= 31 ? 31 : n);
2212 signed32 source = (signed32)*rS; /* signed to keep sign bit */
2213 signed32 shifted = source >> shift;
2214 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
2215 *rA = (signed_word)shifted; /* if 64bit will sign extend */
2216 if (source < 0 && (source & mask))
2220 CR0_COMPARE(shifted, 0, Rc);
2224 # I.3.3.14 Move to/from System Register Instructions
2227 0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
2228 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2229 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2230 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2231 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
2232 int n = (spr{5:9} << 5) | spr{0:4};
2233 if (spr{0} && IS_PROBLEM_STATE(processor))
2234 program_interrupt(processor, cia,
2235 privileged_instruction_program_interrupt);
2236 else if (!spr_is_valid(n)
2237 || spr_is_readonly(n))
2238 program_interrupt(processor, cia,
2239 illegal_instruction_program_interrupt);
2241 spreg new_val = (spr_length(n) == 64
2243 : MASKED(*rS, 32, 63));
2244 /* HACK - time base registers need to be updated immediatly */
2245 if (WITH_TIME_BASE) {
2249 cpu_set_time_base(processor,
2250 (MASKED64(cpu_get_time_base(processor), 32, 63)
2251 | INSERTED64(new_val, 0, 31)));
2254 cpu_set_time_base(processor,
2255 (MASKED64(cpu_get_time_base(processor), 0, 31)
2256 | INSERTED64(new_val, 32, 63)));
2259 cpu_set_decrementer(processor, new_val);
2271 0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
2272 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2273 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2274 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2275 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2276 int n = (spr{5:9} << 5) | spr{0:4};
2277 if (spr{0} && IS_PROBLEM_STATE(processor))
2278 program_interrupt(processor, cia,
2279 privileged_instruction_program_interrupt);
2280 else if (!spr_is_valid(n))
2281 program_interrupt(processor, cia,
2282 illegal_instruction_program_interrupt);
2284 /* HACK - some SPR's need to get their value extracted specially */
2288 # FIXME: 604 uses SCIU{1,2} if only one bit is being set
2289 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
2290 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2291 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2292 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2293 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
2298 unsigned_word mask = 0;
2300 for (f = 0; f < 8; f++) {
2301 if (FXM & (0x80 >> f))
2302 mask |= (0xf << 4*(7-f));
2304 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
2307 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
2309 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
2310 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2311 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2312 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2313 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2314 *rT = (unsigned32)CR;
2317 # I.4.6.2 Floating-Point Load Instructions
2320 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
2321 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2322 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2323 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2324 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2330 *frT = DOUBLE(MEM(unsigned, EA, 4));
2332 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
2333 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2334 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2335 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2336 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2342 *frT = DOUBLE(MEM(unsigned, EA, 4));
2344 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
2345 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2346 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2347 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2348 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2351 program_interrupt(processor, cia,
2352 illegal_instruction_program_interrupt);
2354 *frT = DOUBLE(MEM(unsigned, EA, 4));
2357 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
2358 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2359 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2360 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2361 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2364 program_interrupt(processor, cia,
2365 illegal_instruction_program_interrupt);
2367 *frT = DOUBLE(MEM(unsigned, EA, 4));
2370 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
2371 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2372 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2373 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2374 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2380 *frT = MEM(unsigned, EA, 8);
2382 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
2383 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2384 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2385 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2386 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2392 *frT = MEM(unsigned, EA, 8);
2394 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
2395 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2396 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2397 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2398 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2401 program_interrupt(processor, cia,
2402 illegal_instruction_program_interrupt);
2404 *frT = MEM(unsigned, EA, 8);
2407 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
2408 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2409 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2410 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2411 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2414 program_interrupt(processor, cia,
2415 illegal_instruction_program_interrupt);
2417 *frT = MEM(unsigned, EA, 8);
2422 # I.4.6.3 Floating-Point Store Instructions
2425 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
2426 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2427 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2428 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2429 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2435 STORE(EA, 4, SINGLE(*frS));
2437 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
2438 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2439 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2440 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2441 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2447 STORE(EA, 4, SINGLE(*frS));
2449 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
2450 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2451 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2452 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2453 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2456 program_interrupt(processor, cia,
2457 illegal_instruction_program_interrupt);
2459 STORE(EA, 4, SINGLE(*frS));
2462 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
2463 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2464 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2465 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2466 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2469 program_interrupt(processor, cia,
2470 illegal_instruction_program_interrupt);
2472 STORE(EA, 4, SINGLE(*frS));
2475 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
2476 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2477 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2478 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2479 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2487 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
2488 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2489 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2490 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2491 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2499 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
2500 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2501 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2502 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2503 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2506 program_interrupt(processor, cia,
2507 illegal_instruction_program_interrupt);
2512 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
2513 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2514 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2515 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2516 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2519 program_interrupt(processor, cia,
2520 illegal_instruction_program_interrupt);
2527 # I.4.6.4 Floating-Point Move Instructions
2530 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
2531 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2532 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2533 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2534 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2538 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
2539 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2540 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2541 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2542 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2543 *frT = *frB ^ BIT64(0);
2546 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
2547 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2548 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2549 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2550 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2551 *frT = *frB & ~BIT64(0);
2554 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
2555 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2556 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2557 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2558 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2559 *frT = *frB | BIT64(0);
2565 # I.4.6.5 Floating-Point Arithmetic Instructions
2568 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
2569 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2570 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2571 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2572 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2574 if (is_invalid_operation(processor, cia,
2576 fpscr_vxsnan | fpscr_vxisi,
2579 invalid_arithemetic_operation(processor, cia,
2581 0, /*instruction_is_frsp*/
2582 0, /*instruction_is_convert_to_64bit*/
2583 0, /*instruction_is_convert_to_32bit*/
2584 0); /*single-precision*/
2588 double s = *(double*)frA + *(double*)frB;
2593 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
2594 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2595 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2596 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2597 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2599 if (is_invalid_operation(processor, cia,
2601 fpscr_vxsnan | fpscr_vxisi,
2604 invalid_arithemetic_operation(processor, cia,
2606 0, /*instruction_is_frsp*/
2607 0, /*instruction_is_convert_to_64bit*/
2608 0, /*instruction_is_convert_to_32bit*/
2609 1); /*single-precision*/
2613 float s = *(double*)frA + *(double*)frB;
2618 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
2619 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2620 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2621 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2622 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2624 if (is_invalid_operation(processor, cia,
2626 fpscr_vxsnan | fpscr_vxisi,
2629 invalid_arithemetic_operation(processor, cia,
2631 0, /*instruction_is_frsp*/
2632 0, /*instruction_is_convert_to_64bit*/
2633 0, /*instruction_is_convert_to_32bit*/
2634 0); /*single-precision*/
2638 double s = *(double*)frA - *(double*)frB;
2643 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
2644 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2645 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2646 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2647 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2649 if (is_invalid_operation(processor, cia,
2651 fpscr_vxsnan | fpscr_vxisi,
2654 invalid_arithemetic_operation(processor, cia,
2656 0, /*instruction_is_frsp*/
2657 0, /*instruction_is_convert_to_64bit*/
2658 0, /*instruction_is_convert_to_32bit*/
2659 1); /*single-precision*/
2663 float s = *(double*)frA - *(double*)frB;
2668 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
2669 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2670 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2671 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2672 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2674 if (is_invalid_operation(processor, cia,
2676 fpscr_vxsnan | fpscr_vximz,
2679 invalid_arithemetic_operation(processor, cia,
2681 0, /*instruction_is_frsp*/
2682 0, /*instruction_is_convert_to_64bit*/
2683 0, /*instruction_is_convert_to_32bit*/
2684 0); /*single-precision*/
2688 double s = *(double*)frA * *(double*)frC;
2693 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
2694 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2695 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2696 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2697 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2699 if (is_invalid_operation(processor, cia,
2701 fpscr_vxsnan | fpscr_vximz,
2704 invalid_arithemetic_operation(processor, cia,
2706 0, /*instruction_is_frsp*/
2707 0, /*instruction_is_convert_to_64bit*/
2708 0, /*instruction_is_convert_to_32bit*/
2709 1); /*single-precision*/
2713 float s = *(double*)frA * *(double*)frC;
2718 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
2719 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
2720 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
2721 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
2722 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
2724 if (is_invalid_operation(processor, cia,
2726 fpscr_vxsnan | fpscr_vxzdz,
2729 invalid_arithemetic_operation(processor, cia,
2731 0, /*instruction_is_frsp*/
2732 0, /*instruction_is_convert_to_64bit*/
2733 0, /*instruction_is_convert_to_32bit*/
2734 0); /*single-precision*/
2738 double s = *(double*)frA / *(double*)frB;
2743 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
2744 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
2745 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
2746 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
2747 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
2749 if (is_invalid_operation(processor, cia,
2751 fpscr_vxsnan | fpscr_vxzdz,
2754 invalid_arithemetic_operation(processor, cia,
2756 0, /*instruction_is_frsp*/
2757 0, /*instruction_is_convert_to_64bit*/
2758 0, /*instruction_is_convert_to_32bit*/
2759 1); /*single-precision*/
2763 float s = *(double*)frA / *(double*)frB;
2768 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
2769 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2770 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2771 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2772 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2774 double product; /*HACK! - incorrectly loosing precision ... */
2775 /* compute the multiply */
2776 if (is_invalid_operation(processor, cia,
2778 fpscr_vxsnan | fpscr_vximz,
2781 invalid_arithemetic_operation(processor, cia,
2782 (unsigned64*)&product, *frA, 0, *frC,
2783 0, /*instruction_is_frsp*/
2784 0, /*instruction_is_convert_to_64bit*/
2785 0, /*instruction_is_convert_to_32bit*/
2786 0); /*single-precision*/
2790 product = *(double*)frA * *(double*)frC;
2792 /* compute the add */
2793 if (is_invalid_operation(processor, cia,
2795 fpscr_vxsnan | fpscr_vxisi,
2798 invalid_arithemetic_operation(processor, cia,
2799 frT, product, *frB, 0,
2800 0, /*instruction_is_frsp*/
2801 0, /*instruction_is_convert_to_64bit*/
2802 0, /*instruction_is_convert_to_32bit*/
2803 0); /*single-precision*/
2807 double s = product + *(double*)frB;
2812 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
2813 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2814 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2815 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2816 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2818 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
2819 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2820 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2821 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2822 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2824 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
2825 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2826 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2827 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2828 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2830 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
2831 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2832 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2833 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2834 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2836 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
2837 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2838 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2839 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2840 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2842 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
2843 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2844 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2845 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2846 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2848 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
2849 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2850 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2851 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2852 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2856 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
2859 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
2860 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2861 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2862 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2863 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2866 unsigned64 frac_grx;
2867 /* split off cases for what to do */
2868 if (EXTRACTED64(*frB, 1, 11) < 897
2869 && EXTRACTED64(*frB, 1, 63) > 0) {
2870 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
2871 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
2873 if (EXTRACTED64(*frB, 1, 11) > 1150
2874 && EXTRACTED64(*frB, 1, 11) < 2047) {
2875 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
2876 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
2878 if (EXTRACTED64(*frB, 1, 11) > 896
2879 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
2880 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
2881 if (EXTRACTED64(*frB, 1, 11) == 2047) {
2882 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
2883 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
2884 if (EXTRACTED64(*frB, 12, 12) == 0
2885 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
2888 Disabled_Exponent_Underflow:
2889 sign = EXTRACTED64(*frB, 0, 0);
2890 if (EXTRACTED64(*frB, 1, 11) == 0) {
2892 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2894 if (EXTRACTED64(*frB, 1, 11) > 0) {
2895 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2896 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2898 Denormalize_Operand:
2899 /* G|R|X == zero from above */
2900 while (exp < -126) {
2902 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
2903 | MASKED64(frac_grx, 55, 55));
2905 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
2906 Round_Single(processor, sign, &exp, &frac_grx);
2907 FPSCR_SET_XX(FPSCR & fpscr_fi);
2908 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
2909 *frT = INSERTED64(sign, 0, 0);
2910 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
2911 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
2913 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
2914 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
2915 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2916 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2918 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
2919 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
2920 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
2922 /*Normalize_Operand:*/
2923 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
2925 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
2927 *frT = (INSERTED64(sign, 0, 0)
2928 | INSERTED64(exp + 1023, 1, 11)
2929 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2932 Enabled_Exponent_Underflow:
2934 sign = EXTRACTED64(*frB, 0, 0);
2935 if (EXTRACTED64(*frB, 1, 11) == 0) {
2937 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2939 if (EXTRACTED64(*frB, 1, 11) > 0) {
2940 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2941 frac_grx = (BIT64(0) |
2942 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
2944 /*Normalize_Operand:*/
2945 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
2947 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
2949 Round_Single(processor, sign, &exp, &frac_grx);
2950 FPSCR_SET_XX(FPSCR & fpscr_fi);
2952 *frT = (INSERTED64(sign, 0, 0)
2953 | INSERTED64(exp + 1023, 1, 11)
2954 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2955 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2956 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2958 Disabled_Exponent_Overflow:
2960 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
2961 if (EXTRACTED64(*frB, 0, 0) == 0) {
2962 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
2963 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
2965 if (EXTRACTED64(*frB, 0, 0) == 1) {
2966 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
2967 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
2970 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
2971 if (EXTRACTED64(*frB, 0, 0) == 0) {
2972 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
2973 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2975 if (EXTRACTED64(*frB, 0, 0) == 1) {
2976 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
2977 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2980 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
2981 if (EXTRACTED64(*frB, 0, 0) == 0) {
2982 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
2983 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
2985 if (EXTRACTED64(*frB, 0, 0) == 1) {
2986 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
2987 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2990 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
2991 if (EXTRACTED64(*frB, 0, 0) == 0) {
2992 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
2993 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2995 if (EXTRACTED64(*frB, 0, 0) == 1) {
2996 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
2997 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3000 /* FPSCR[FR] <- undefined */
3004 Enabled_Exponent_Overflow:
3005 sign = EXTRACTED64(*frB, 0, 0);
3006 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3007 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3008 Round_Single(processor, sign, &exp, &frac_grx);
3009 FPSCR_SET_XX(FPSCR & fpscr_fi);
3013 *frT = (INSERTED64(sign, 0, 0)
3014 | INSERTED64(exp + 1023, 1, 11)
3015 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3016 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3017 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3021 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3022 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3028 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3029 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3034 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
3035 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
3040 FPSCR_OR_VX(fpscr_vxsnan);
3041 if ((FPSCR & fpscr_ve) == 0) {
3042 *frT = (MASKED64(*frB, 0, 11)
3044 | MASKED64(*frB, 13, 34));
3045 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
3051 sign = EXTRACTED64(*frB, 0, 0);
3052 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3053 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3054 Round_Single(processor, sign, &exp, &frac_grx);
3055 FPSCR_SET_XX(FPSCR & fpscr_fi);
3056 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3057 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
3058 *frT = (INSERTED64(sign, 0, 0)
3059 | INSERTED64(exp + 1023, 1, 11)
3060 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3061 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3062 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3066 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
3068 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
3070 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
3072 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
3073 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3074 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3075 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3076 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3078 convert_to_integer(processor, cia,
3080 fpscr_rn_round_towards_zero, 32);
3083 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
3084 int sign = EXTRACTED64(*frB, 0, 0);
3086 unsigned64 frac = *frB;
3087 if (frac == 0) goto Zero_Operand;
3088 if (sign == 1) frac = ~frac + 1;
3089 while (EXTRACTED64(frac, 0, 0) == 0) {
3090 /*??? do the loop 0 times if (FRB) = max negative integer */
3091 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
3094 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
3095 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3096 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3097 *frT = (INSERTED64(sign, 0, 0)
3098 | INSERTED64(exp + 1023, 1, 11)
3099 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
3105 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3112 # I.4.6.7 Floating-Point Compare Instructions
3115 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
3116 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3117 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3118 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3119 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3122 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3123 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3124 else if (is_less_than(frA, frB))
3125 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3126 else if (is_greater_than(frA, frB))
3127 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3129 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3131 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3132 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
3133 FPSCR_OR_VX(fpscr_vxsnan);
3136 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
3137 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3138 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3139 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3140 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3143 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3144 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3145 else if (is_less_than(frA, frB))
3146 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3147 else if (is_greater_than(frA, frB))
3148 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3150 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3152 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3153 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
3154 FPSCR_OR_VX(fpscr_vxsnan);
3155 if ((FPSCR & fpscr_ve) == 0)
3156 FPSCR_OR_VX(fpscr_vxvc);
3158 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
3159 FPSCR_OR_VX(fpscr_vxvc);
3165 # I.4.6.8 Floating-Point Status and Control Register Instructions
3168 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
3170 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
3172 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
3174 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
3176 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
3178 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
3182 # I.A.1.1 Floating-Point Store Instruction
3184 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
3187 # I.A.1.2 Floating-Point Arithmetic Instructions
3190 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
3192 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
3194 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
3196 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
3199 # I.A.1.3 Floating-Point Select Instruction
3202 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
3206 # II.3.2 Cache Management Instructions
3209 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
3210 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3211 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3212 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3213 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3214 /* blindly flush all instruction cache entries */
3215 #if WITH_IDECODE_CACHE_SIZE
3216 cpu_flush_icache(processor);
3219 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
3220 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3221 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3222 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3223 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3224 cpu_synchronize_context(processor);
3228 # II.3.2.2 Data Cache Instructions
3231 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
3232 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3233 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
3234 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
3235 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3236 TRACE(trace_tbd,("Data Cache Block Touch\n"));
3238 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
3239 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3240 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
3241 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
3242 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3243 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
3245 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
3246 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3247 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, PPC_SERIALIZE
3248 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, PPC_SERIALIZE
3249 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3250 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
3252 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
3253 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3254 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, PPC_SERIALIZE
3255 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, PPC_SERIALIZE
3256 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3257 TRACE(trace_tbd,("Data Cache Block Store\n"));
3259 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
3260 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3261 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, PPC_SERIALIZE
3262 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, PPC_SERIALIZE
3263 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3264 TRACE(trace_tbd,("Data Cache Block Flush\n"));
3267 # II.3.3 Enforce In-order Execution of I/O Instruction
3270 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
3271 /* Since this model has no instruction overlap
3272 this instruction need do nothing */
3275 # II.4.1 Time Base Instructions
3278 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
3279 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3280 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3281 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3282 int n = (tbr{5:9} << 5) | tbr{0:4};
3284 if (is_64bit_implementation) *rT = TB;
3285 else *rT = EXTRACTED64(TB, 32, 63);
3287 else if (n == 269) {
3288 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
3289 else *rT = EXTRACTED64(TB, 0, 31);
3292 program_interrupt(processor, cia,
3293 illegal_instruction_program_interrupt);
3297 # III.2.3.1 System Linkage Instructions
3300 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
3301 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3302 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3303 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3304 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, PPC_SERIALIZE
3305 if (IS_PROBLEM_STATE(processor)) {
3306 program_interrupt(processor, cia,
3307 privileged_instruction_program_interrupt);
3310 MSR = (MASKED(SRR1, 0, 32)
3311 | MASKED(SRR1, 37, 41)
3312 | MASKED(SRR1, 48, 63));
3313 NIA = MASKED(SRR0, 0, 61);
3314 cpu_synchronize_context(processor);
3318 # III.3.4.1 Move to/from System Register Instructions
3321 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
3322 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
3323 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
3324 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3325 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3326 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3327 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3328 if (IS_PROBLEM_STATE(processor))
3329 program_interrupt(processor, cia,
3330 privileged_instruction_program_interrupt);
3334 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
3335 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3336 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, PPC_SERIALIZE
3337 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, PPC_SERIALIZE
3338 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, PPC_SERIALIZE
3339 if (IS_PROBLEM_STATE(processor))
3340 program_interrupt(processor, cia,
3341 privileged_instruction_program_interrupt);
3347 # III.4.11.1 Cache Management Instructions
3350 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
3351 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3352 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, PPC_SERIALIZE
3353 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, PPC_SERIALIZE
3354 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3355 if (IS_PROBLEM_STATE(processor))
3356 program_interrupt(processor, cia,
3357 privileged_instruction_program_interrupt);
3359 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
3362 # III.4.11.2 Segment Register Manipulation Instructions
3365 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
3366 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3367 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3368 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3369 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3370 if (IS_PROBLEM_STATE(processor))
3371 program_interrupt(processor, cia,
3372 privileged_instruction_program_interrupt);
3376 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
3377 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3378 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3379 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3380 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3381 if (IS_PROBLEM_STATE(processor))
3382 program_interrupt(processor, cia,
3383 privileged_instruction_program_interrupt);
3385 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
3387 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
3388 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3389 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3390 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3391 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3392 if (IS_PROBLEM_STATE(processor))
3393 program_interrupt(processor, cia,
3394 privileged_instruction_program_interrupt);
3398 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
3399 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3400 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3401 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3402 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3403 if (IS_PROBLEM_STATE(processor))
3404 program_interrupt(processor, cia,
3405 privileged_instruction_program_interrupt);
3407 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
3411 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
3414 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
3416 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
3418 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
3420 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
3422 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
3426 # III.A.1.2 External Access Instructions
3429 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
3431 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed