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_word old_program_counter; /* previous PC */
108 unsigned nr_branches; /* # branches */
109 unsigned nr_units[nr_ppc_function_units]; /* function unit counts */
110 unsigned16 busy[nr_ppc_function_units]; /* how long until free */
113 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
114 "unknown functional unit instruction",
115 "integer functional unit instruction",
116 "system register functional unit instruction",
117 "1st single cycle integer functional unit instruction",
118 "2nd single cycle integer functional unit instruction",
119 "multiple cycle integer functional unit instruction",
120 "floating point functional unit instruction",
121 "load/store functional unit instruction",
122 "branch functional unit instruction",
125 model_data *::model-function::model_create:cpu *processor
126 if (CURRENT_MODEL == MODEL_NONE) {
127 error("Must define a CPU model");
128 return (model_data *)0;
131 model_data *model_ptr = ZALLOC(model_data);
132 model_ptr->name = model_name[CURRENT_MODEL];
133 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
137 void::model-function::model_init:cpu *processor, model_data *model_ptr
139 void::model-function::model_halt:cpu *processor, model_data *model_ptr
141 void::model-function::model_issue:itable_index index, cpu *processor, model_data *model_ptr, unsigned_word cia
142 if (model_ptr->old_program_counter+4 != cia)
143 model_ptr->nr_branches++;
145 model_ptr->old_program_counter = cia;
146 model_ptr->nr_units[ (int)model_ptr->timing[ (int)index ].first_unit ]++;
148 /* Assume that any instruction we don't know about is illegal for this
150 if (model_ptr->timing[(int)index].first_unit == PPC_UNIT_BAD)
151 program_interrupt(processor, cia,
152 illegal_instruction_program_interrupt);
154 model_print *::model-function::model_mon_info:model_data *model_ptr
159 head = tail = ZALLOC(model_print);
160 tail->count = model_ptr->nr_branches;
161 tail->name = "branch";
162 tail->suffix_plural = "es";
163 tail->suffix_singular = "";
165 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
166 if (model_ptr->nr_units[i]) {
167 tail->next = ZALLOC(model_print);
169 tail->count = model_ptr->nr_units[i];
170 tail->name = ppc_function_unit_name[i];
171 tail->suffix_plural = "s";
172 tail->suffix_singular = "";
176 tail->next = (model_print *)0;
179 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
189 # The following (illegal) instruction is `known' by gen and is
190 # called when ever an illegal instruction is encountered
192 program_interrupt(processor, cia,
193 illegal_instruction_program_interrupt);
197 # The following (floating point unavailable) instruction is `known' by gen
198 # and is called when ever an a floating point instruction is to be
199 # executed but floating point is make unavailable by the MSR
200 ::internal::floating_point_unavailable
201 floating_point_unavailable_interrupt(processor, cia);
206 # Floating point support functions
209 # Convert 32bit single to 64bit double
210 unsigned64::function::DOUBLE:unsigned32 WORD
212 if (EXTRACTED32(WORD, 1, 8) > 0
213 && EXTRACTED32(WORD, 1, 8) < 255) {
214 /* normalized operand */
215 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
216 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
217 | INSERTED64(not_word_1_1, 2, 2)
218 | INSERTED64(not_word_1_1, 3, 3)
219 | INSERTED64(not_word_1_1, 4, 4)
220 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
222 else if (EXTRACTED32(WORD, 1, 8) == 0
223 && EXTRACTED32(WORD, 9, 31) != 0) {
224 /* denormalized operand */
225 int sign = EXTRACTED32(WORD, 0, 0);
227 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
228 /* normalize the operand */
229 while (MASKED64(frac, 0, 0) == 0) {
233 FRT = (INSERTED64(sign, 0, 0)
234 | INSERTED64(exp + 1023, 1, 11)
235 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
237 else if (EXTRACTED32(WORD, 1, 8) == 255
238 || EXTRACTED32(WORD, 1, 31) == 0) {
239 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
240 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
241 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
242 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
243 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
246 error("DOUBLE - unknown case\n");
251 # Convert 64bit single to 32bit double
252 unsigned32::function::SINGLE:unsigned64 FRS
254 if (EXTRACTED64(FRS, 1, 11) > 896
255 || EXTRACTED64(FRS, 1, 63) == 0) {
256 /* no denormalization required (includes Zero/Infinity/NaN) */
257 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
258 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
260 else if (874 <= EXTRACTED64(FRS, 1, 11)
261 && EXTRACTED64(FRS, 1, 11) <= 896) {
262 /* denormalization required */
263 int sign = EXTRACTED64(FRS, 0, 0);
264 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
265 unsigned64 frac = (BIT64(0)
266 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
267 /* denormalize the operand */
269 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
272 WORD = (INSERTED32(sign, 0, 0)
273 | INSERTED32(0x00, 1, 8)
274 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
277 WORD = 0x0; /* ??? */
282 # round 64bit double to 64bit but single
283 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
284 /* comparisons ignore u bits */
287 int lsb = EXTRACTED64(*frac_grx, 23, 23);
288 int gbit = EXTRACTED64(*frac_grx, 24, 24);
289 int rbit = EXTRACTED64(*frac_grx, 25, 25);
290 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
291 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
292 if (lsb == 1 && gbit == 1) inc = 1;
293 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
294 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
296 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
297 if (sign == 0 && gbit == 1) inc = 1;
298 if (sign == 0 && rbit == 1) inc = 1;
299 if (sign == 0 && xbit == 1) inc = 1;
301 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
302 if (sign == 1 && gbit == 1) inc = 1;
303 if (sign == 1 && rbit == 1) inc = 1;
304 if (sign == 1 && xbit == 1) inc = 1;
306 /* work out addition in low 25 bits of out */
307 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
308 *frac_grx = INSERTED64(out, 0, 23);
309 if (out & BIT64(64 - 23 - 1 - 1)) {
310 *frac_grx = (BIT64(0) |
311 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
314 /* frac_grx[24:52] = 0 already */
316 FPSCR_SET_FI(gbit || rbit || xbit);
320 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
322 if (round_mode == fpscr_rn_round_to_nearest) {
323 if (*frac64 == 1 && gbit == 1) inc = 1;
324 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
325 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
327 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
328 if (sign == 0 && gbit == 1) inc = 1;
329 if (sign == 0 && rbit == 1) inc = 1;
330 if (sign == 0 && xbit == 1) inc = 1;
332 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
333 if (sign == 1 && gbit == 1) inc = 1;
334 if (sign == 1 && rbit == 1) inc = 1;
335 if (sign == 1 && xbit == 1) inc = 1;
337 /* frac[0:64] = frac[0:64} + inc */
338 *frac += (*frac64 && inc ? 1 : 0);
339 *frac64 = (*frac64 + inc) & 0x1;
341 FPSCR_SET_FI(gbit | rbit | xbit);
344 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
347 int lsb = EXTRACTED64(*frac, 52, 52);
348 int gbit = EXTRACTED64(*frac, 53, 53);
349 int rbit = EXTRACTED64(*frac, 54, 54);
350 int xbit = EXTRACTED64(*frac, 55, 55);
351 if (round_mode == fpscr_rn_round_to_nearest) {
352 if (lsb == 1 && gbit == 1) inc = 1;
353 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
354 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
356 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
357 if (sign == 0 && gbit == 1) inc = 1;
358 if (sign == 0 && rbit == 1) inc = 1;
359 if (sign == 0 && xbit == 1) inc = 1;
361 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
362 if (sign == 1 && gbit == 1) inc = 1;
363 if (sign == 1 && rbit == 1) inc = 1;
364 if (sign == 1 && xbit == 1) inc = 1;
366 /* frac//carry_out = frac + inc */
367 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
368 carry_out = EXTRACTED64(*frac, 0, 0);
370 if (carry_out == 1) *exp = *exp + 1;
372 FPSCR_SET_FI(gbit | rbit | xbit);
373 FPSCR_SET_XX(FPSCR & fpscr_fi);
376 # conversion of FP to integer
377 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
385 int sign = EXTRACTED64(frb, 0, 0);
386 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
387 goto Infinity_Operand;
388 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
390 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
392 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
393 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
394 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
395 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
396 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
399 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
400 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
403 gbit = 0, rbit = 0, xbit = 0;
404 for (i = 1; i <= 63 - exp; i++) {
408 frac64 = EXTRACTED64(frac, 63, 63);
409 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
411 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
412 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
415 frac += (frac64 ? 1 : 0);
416 frac64 = (frac64 + 1) & 0x1;
418 if (tgt_precision == 32 /* can ignore frac64 in compare */
419 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
421 if (tgt_precision == 64 /* can ignore frac64 in compare */
422 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
424 if (tgt_precision == 32 /* can ignore frac64 in compare */
425 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
427 if (tgt_precision == 64 /* can ignore frac64 in compare */
428 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
430 FPSCR_SET_XX(FPSCR & fpscr_fi);
431 if (tgt_precision == 32)
432 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
433 if (tgt_precision == 64)
434 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
435 /*FPSCR[fprf] = undefined */
441 FPSCR_OR_VX(fpscr_vxcvi);
442 if ((FPSCR & fpscr_ve) == 0) {
443 if (tgt_precision == 32) {
444 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
445 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
448 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
449 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
451 /* FPSCR[FPRF] = undefined */
458 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
459 if ((FPSCR & fpscr_ve) == 0) {
460 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
461 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
462 /* FPSCR[fprf] = undefined */
469 FPSCR_OR_VX(fpscr_vxcvi);
470 if ((FPSCR & fpscr_ve) == 0) {
471 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
472 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
473 /* FPSCR[fprf] = undefined */
480 FPSCR_OR_VX(fpscr_vxcvi);
481 if ((FPSCR & fpscr_ve) == 0) {
482 if (tgt_precision == 32) {
483 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
484 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
487 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
488 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
490 /* FPSCR[fprf] = undefined */
496 # extract out raw fields of a FP number
497 int::function::sign:unsigned64 FRS
498 return (MASKED64(FRS, 0, 0)
501 int::function::biased_exp:unsigned64 frs, int single
503 return EXTRACTED64(frs, 1, 8);
505 return EXTRACTED64(frs, 1, 11);
506 unsigned64::function::fraction:unsigned64 frs, int single
508 return EXTRACTED64(frs, 9, 31);
510 return EXTRACTED64(frs, 12, 63);
512 # a number?, each of the below return +1 or -1 (based on sign bit)
514 int::function::is_nor:unsigned64 frs, int single
515 int exp = biased_exp(frs, single);
517 && exp <= (single ? 254 : 2046));
518 int::function::is_zero:unsigned64 FRS
519 return (MASKED64(FRS, 1, 63) == 0
522 int::function::is_den:unsigned64 frs, int single
523 int exp = biased_exp(frs, single);
524 unsigned64 frac = fraction(frs, single);
525 return (exp == 0 && frac != 0
528 int::function::is_inf:unsigned64 frs, int single
529 int exp = biased_exp(frs, single);
530 int frac = fraction(frs, single);
531 return (exp == (single ? 255 : 2047) && frac == 0
534 int::function::is_NaN:unsigned64 frs, int single
535 int exp = biased_exp(frs, single);
536 int frac = fraction(frs, single);
537 return (exp == (single ? 255 : 2047) && frac != 0
540 int::function::is_SNaN:unsigned64 frs, int single
541 return (is_NaN(frs, single)
542 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
545 int::function::is_QNaN:unsigned64 frs, int single
546 return (is_NaN(frs, single) && !is_SNaN(frs, single));
547 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
548 return *(double*)fra < *(double*)frb;
549 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
550 return *(double*)fra > *(double*)frb;
551 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
552 return *(double*)fra == *(double*)frb;
555 # which quiet nan should become the result
556 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
558 if (is_NaN(fra, single))
560 else if (is_NaN(frb, single))
561 if (instruction_is_frsp)
562 frt = MASKED64(frb, 0, 34);
565 else if (is_NaN(frc, single))
567 else if (generate_qnan)
568 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
570 error("select_qnan - default reached\n");
574 # detect invalid operation
575 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
577 if ((check & fpscr_vxsnan)
578 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
579 FPSCR_OR_VX(fpscr_vxsnan);
582 if ((check & fpscr_vxisi)
583 && (is_inf(fra, single) && is_inf(frb, single))
584 && ((negate && sign(fra) != sign(frb))
585 || (!negate && sign(fra) == sign(frb)))) {
586 /*FIXME: don't handle inf-inf VS inf+-inf */
587 FPSCR_OR_VX(fpscr_vxisi);
590 if ((check & fpscr_vxidi)
591 && (is_inf(fra, single) && is_inf(frb, single))) {
592 FPSCR_OR_VX(fpscr_vxidi);
595 if ((check & fpscr_vxzdz)
596 && (is_zero(fra) && is_zero(frb))) {
597 FPSCR_OR_VX(fpscr_vxzdz);
600 if ((check & fpscr_vximz)
601 && (is_zero(fra) && is_inf(frb, single))) {
602 FPSCR_OR_VX(fpscr_vximz);
605 if ((check & fpscr_vxvc)
606 && (is_NaN(fra, single) || is_NaN(frb, single))) {
607 FPSCR_OR_VX(fpscr_vxvc);
610 if ((check & fpscr_vxsoft)) {
611 FPSCR_OR_VX(fpscr_vxsoft);
614 if ((check & fpscr_vxsqrt)
616 FPSCR_OR_VX(fpscr_vxsqrt);
619 /* if ((check && fpscr_vxcvi) {
620 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
621 FPSCR_OR_VX(fpscr_vxcvi);
631 # handle case of invalid operation
632 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
633 if (FPSCR & fpscr_ve) {
634 /* invalid operation exception enabled */
638 /* fpscr_FPRF unchanged */
641 /* invalid operation exception disabled */
642 if (instruction_is_convert_to_64bit) {
645 else if (instruction_is_convert_to_32bit) {
648 else { /* arrith, frsp */
649 *frt = select_qnan(fra, frb, frc,
650 instruction_is_frsp, 0/*generate*/, single);
653 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
661 # I.2.4.1 Branch Instructions
663 0.18,6.LI,30.AA,31.LK:I:t::Branch
664 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
665 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
666 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
667 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
668 if (AA) NIA = IEA(EXTS(LI_0b00));
669 else NIA = IEA(CIA + EXTS(LI_0b00));
670 if (LK) LR = (spreg)CIA+4;
671 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
672 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
673 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
674 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
675 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
676 int M, ctr_ok, cond_ok;
677 if (is_64bit_implementation && is_64bit_mode) M = 0;
679 if (!BO{2}) CTR = CTR - 1;
680 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
681 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
682 if (ctr_ok && cond_ok)
683 if (AA) NIA = IEA(EXTS(BD_0b00));
684 else NIA = IEA(CIA + EXTS(BD_0b00));
685 if (LK) LR = (spreg)IEA(CIA + 4);
686 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
687 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
688 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
689 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
690 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
691 int M, ctr_ok, cond_ok;
692 if (is_64bit_implementation && is_64bit_mode) M = 0;
694 if (!BO{2}) CTR = CTR - 1;
695 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
696 cond_ok = BO{0} || (CR{BI} == BO{1});
697 if (ctr_ok && cond_ok) NIA = IEA(LR_0b00);
698 if (LK) LR = (spreg)IEA(CIA + 4);
699 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
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
705 cond_ok = BO{0} || (CR{BI} == BO{1});
706 if (cond_ok) NIA = IEA(CTR_0b00);
707 if (LK) LR = (spreg)IEA(CIA + 4);
710 # I.2.4.2 System Call Instruction
712 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
713 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
714 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
715 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
716 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, PPC_SERIALIZE
717 system_call_interrupt(processor, cia);
720 # I.2.4.3 Condition Register Logical Instructions
722 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
723 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
724 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
725 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
726 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
727 BLIT32(CR, BT, CR{BA} && CR{BB});
729 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
730 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
731 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
732 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
733 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
734 BLIT32(CR, BT, CR{BA} || CR{BB});
736 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
737 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
738 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
739 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
740 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
741 BLIT32(CR, BT, CR{BA} != CR{BB});
743 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
744 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
745 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
746 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
747 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
748 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
750 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
751 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
752 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
753 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
754 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
755 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
757 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
758 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
759 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
760 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
761 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
762 BLIT32(CR, BT, CR{BA} == CR{BB});
764 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
765 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
766 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
767 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
768 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
769 BLIT32(CR, BT, CR{BA} && !CR{BB});
771 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
772 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
773 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
774 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
775 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
776 BLIT32(CR, BT, CR{BA} || !CR{BB});
779 # I.2.4.4 Condition Register Field Instruction
781 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
782 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
783 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
784 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
785 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
786 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
790 # I.3.3.2 Fixed-Point Load Instructions
793 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
794 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
795 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
796 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
797 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
803 *rT = MEM(unsigned, EA, 1);
805 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
806 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
807 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
808 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
809 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
815 *rT = MEM(unsigned, EA, 1);
817 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
818 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
819 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
820 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
821 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
823 if (RA == 0 || RA == RT)
824 program_interrupt(processor, cia,
825 illegal_instruction_program_interrupt);
827 *rT = MEM(unsigned, EA, 1);
830 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
831 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
832 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
833 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
834 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
836 if (RA == 0 || RA == RT)
837 program_interrupt(processor, cia,
838 illegal_instruction_program_interrupt);
840 *rT = MEM(unsigned, EA, 1);
843 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
844 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
845 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
846 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
847 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
853 *rT = MEM(unsigned, EA, 2);
855 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
856 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
857 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
858 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
859 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
865 *rT = MEM(unsigned, EA, 2);
866 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
867 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
868 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
869 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
870 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
872 if (RA == 0 || RA == RT)
873 program_interrupt(processor, cia,
874 illegal_instruction_program_interrupt);
876 *rT = MEM(unsigned, EA, 2);
879 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
880 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
881 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
882 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
883 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
885 if (RA == 0 || RA == RT)
886 program_interrupt(processor, cia,
887 illegal_instruction_program_interrupt);
889 *rT = MEM(unsigned, EA, 2);
892 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
893 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
894 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
895 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
896 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
902 *rT = MEM(signed, EA, 2);
904 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
905 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
906 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
907 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
908 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
914 *rT = MEM(signed, EA, 2);
916 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
917 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
918 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
919 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
920 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
922 if (RA == 0 || RA == RT)
923 program_interrupt(processor, cia,
924 illegal_instruction_program_interrupt);
926 *rT = MEM(signed, EA, 2);
928 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
929 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
930 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
931 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
932 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
934 if (RA == 0 || RA == RT)
935 program_interrupt(processor, cia,
936 illegal_instruction_program_interrupt);
938 *rT = MEM(signed, EA, 2);
941 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
942 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
943 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
944 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
945 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
951 *rT = MEM(unsigned, EA, 4);
953 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
954 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
955 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
956 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
957 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
963 *rT = MEM(unsigned, EA, 4);
965 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
966 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
967 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
968 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
969 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
971 if (RA == 0 || RA == RT)
972 program_interrupt(processor, cia,
973 illegal_instruction_program_interrupt);
975 *rT = MEM(unsigned, EA, 4);
978 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
979 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
980 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
981 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
982 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
984 if (RA == 0 || RA == RT)
985 program_interrupt(processor, cia,
986 illegal_instruction_program_interrupt);
988 *rT = MEM(unsigned, EA, 4);
991 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
994 # if (RA == 0) b = 0;
996 # EA = b + EXTS(DS_0b00);
997 # *rT = MEM(signed, EA, 4);
999 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1002 # if (RA == 0) b = 0;
1005 # *rT = MEM(signed, EA, 4);
1007 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1009 # if (RA == 0 || RA == RT)
1010 # program_interrupt(processor, cia
1011 # illegal_instruction_program_interrupt);
1013 # *rT = MEM(signed, EA, 4);
1016 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1019 # if (RA == 0) b = 0;
1021 # EA = b + EXTS(DS_0b00);
1022 # *rT = MEM(unsigned, EA, 8);
1024 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1027 # if (RA == 0) b = 0;
1030 # *rT = MEM(unsigned, EA, 8);
1032 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1034 # if (RA == 0 || RA == RT)
1035 # program_interrupt(processor, cia
1036 # illegal_instruction_program_interrupt);
1037 # EA = *rA + EXTS(DS_0b00);
1038 # *rT = MEM(unsigned, EA, 8);
1041 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1043 # if (RA == 0 || RA == RT)
1044 # program_interrupt(processor, cia
1045 # illegal_instruction_program_interrupt);
1047 # *rT = MEM(unsigned, EA, 8);
1053 # I.3.3.3 Fixed-Point Store Instructions
1056 0.38,6.RS,11.RA,16.D:D:::Store Byte
1057 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1058 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1059 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1060 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1068 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1069 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1070 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1071 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1072 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1080 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1081 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1082 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1083 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1084 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1087 program_interrupt(processor, cia,
1088 illegal_instruction_program_interrupt);
1093 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1094 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1095 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1096 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1097 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1100 program_interrupt(processor, cia,
1101 illegal_instruction_program_interrupt);
1106 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1107 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1108 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1109 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1110 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1118 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1119 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1120 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1121 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1122 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1130 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1131 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1132 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1133 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1134 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1137 program_interrupt(processor, cia,
1138 illegal_instruction_program_interrupt);
1143 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1144 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1145 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1146 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1147 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1150 program_interrupt(processor, cia,
1151 illegal_instruction_program_interrupt);
1156 0.36,6.RS,11.RA,16.D:D:::Store Word
1157 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1158 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1159 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1160 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1168 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
1169 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1170 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1171 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1172 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1180 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
1181 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1182 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1183 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1184 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1187 program_interrupt(processor, cia,
1188 illegal_instruction_program_interrupt);
1193 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
1194 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1195 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1196 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1197 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1200 program_interrupt(processor, cia,
1201 illegal_instruction_program_interrupt);
1206 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
1209 # if (RA == 0) b = 0;
1211 # EA = b + EXTS(DS_0b00);
1212 # STORE(EA, 8, *rS);
1213 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
1216 # if (RA == 0) b = 0;
1219 # STORE(EA, 8, *rS);
1220 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
1223 # program_interrupt(processor, cia
1224 # illegal_instruction_program_interrupt);
1225 # EA = *rA + EXTS(DS_0b00);
1226 # STORE(EA, 8, *rS);
1228 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
1231 # program_interrupt(processor, cia
1232 # illegal_instruction_program_interrupt);
1234 # STORE(EA, 8, *rS);
1239 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
1242 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
1243 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1244 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1245 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1246 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1252 *rT = SWAP_2(MEM(unsigned, EA, 2));
1254 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
1255 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1256 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1257 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1258 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1264 *rT = SWAP_4(MEM(unsigned, EA, 4));
1266 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
1267 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1268 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1269 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1270 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1276 STORE(EA, 2, SWAP_2(*rS));
1278 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
1279 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1280 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1281 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1282 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1288 STORE(EA, 4, SWAP_4(*rS));
1292 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
1295 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
1297 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
1301 # I.3.3.6 Fixed-Point Move Assist Instructions
1304 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
1306 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
1308 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
1310 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
1314 # I.3.3.7 Storage Synchronization Instructions
1316 # HACK: Rather than monitor addresses looking for a reason
1317 # to cancel a reservation. This code instead keeps
1318 # a copy of the data read from memory. Before performing
1319 # a store, the memory area is checked to see if it has
1321 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
1322 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1323 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
1324 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
1325 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
1332 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1333 RESERVE_DATA = MEM(unsigned, EA, 4);
1336 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
1343 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1344 RESERVE_DATA = MEM(unsigned, EA, 8);
1347 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
1348 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1349 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
1350 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
1351 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
1358 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1359 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
1361 CR_SET_XER_SO(0, cr_i_zero);
1364 /* ment to randomly to store, we never do! */
1365 CR_SET_XER_SO(0, 0);
1370 CR_SET_XER_SO(0, 0);
1372 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
1379 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1380 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
1382 CR_SET_XER_SO(0, cr_i_zero);
1385 /* ment to randomly to store, we never do */
1386 CR_SET_XER_SO(0, 0);
1391 CR_SET_XER_SO(0, 0);
1394 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
1395 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
1396 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, PPC_SERIALIZE
1397 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, PPC_SERIALIZE
1398 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
1403 # I.3.3.9 Fixed-Point Arithmetic Instructions
1406 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
1407 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1408 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1409 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1410 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1411 if (RA_is_0) *rT = EXTS(SI);
1412 else *rT = *rA + EXTS(SI);
1414 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
1415 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1416 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1417 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1418 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1419 if (RA_is_0) *rT = EXTS(SI) << 16;
1420 else *rT = *rA + (EXTS(SI) << 16);
1422 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
1423 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1424 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1425 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1426 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1429 ALU_END(*rT, 0/*CA*/, OE, Rc);
1431 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
1432 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1433 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1434 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1435 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1440 ALU_END(*rT, 0/*CA*/, OE, Rc);
1442 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
1443 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1444 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1445 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1446 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1449 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1451 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
1452 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1453 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1454 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1455 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1458 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
1460 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
1461 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1462 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1463 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1464 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1469 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1471 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
1472 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1473 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1474 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1475 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1478 ALU_END(*rT, 1/*CA*/, OE, Rc);
1480 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
1481 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1482 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1483 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1484 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1485 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
1490 ALU_END(*rT, 1/*CA*/, OE, Rc);
1492 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
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_IU, 1, 1, 0
1496 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1500 ALU_END(*rT, 1/*CA*/, OE, Rc);
1502 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
1503 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1504 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1505 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1506 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1511 ALU_END(*rT, 1/*CA*/, OE, Rc);
1513 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
1514 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1515 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1516 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1517 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1521 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1523 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
1524 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1525 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1526 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1527 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1532 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1534 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
1535 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1536 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1537 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1538 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1541 ALU_END(*rT, 1/*CA*/, OE, Rc);
1543 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
1544 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1545 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1546 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1547 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1551 ALU_END(*rT, 1/*CA*/, OE, Rc);
1553 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
1554 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1555 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1556 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1557 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1561 ALU_END(*rT,0/*CA*/,OE,Rc);
1563 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
1564 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1565 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
1566 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
1567 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
1568 signed_word prod = *rA * EXTS(SI);
1571 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
1573 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
1574 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1575 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1576 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1577 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
1578 signed64 a = (signed32)(*rA);
1579 signed64 b = (signed32)(*rB);
1580 signed64 prod = a * b;
1581 signed_word t = prod;
1583 if (t != prod && OE)
1584 XER |= (xer_overflow | xer_summary_overflow);
1585 CR0_COMPARE(t, 0, Rc);
1587 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
1589 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
1590 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1591 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1592 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
1593 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
1594 signed64 a = (signed32)(*rA);
1595 signed64 b = (signed32)(*rB);
1596 signed64 prod = a * b;
1597 signed_word t = EXTRACTED64(prod, 0, 31);
1599 CR0_COMPARE(t, 0, Rc);
1601 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
1603 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
1604 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
1605 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
1606 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
1607 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
1608 unsigned64 a = (unsigned32)(*rA);
1609 unsigned64 b = (unsigned32)(*rB);
1610 unsigned64 prod = a * b;
1611 signed_word t = EXTRACTED64(prod, 0, 31);
1613 CR0_COMPARE(t, 0, Rc);
1615 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
1617 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
1618 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
1619 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
1620 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
1621 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
1622 signed64 dividend = (signed32)(*rA);
1623 signed64 divisor = (signed32)(*rB);
1624 if (divisor == 0 /* nb 0x8000..0 is sign extended */
1625 || (dividend == 0x80000000 && divisor == -1)) {
1627 XER |= (xer_overflow | xer_summary_overflow);
1628 CR0_COMPARE(0, 0, Rc);
1631 signed64 quotent = dividend / divisor;
1633 CR0_COMPARE((signed_word)quotent, 0, Rc);
1635 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
1637 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
1638 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
1639 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
1640 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
1641 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
1642 unsigned64 dividend = (unsigned32)(*rA);
1643 unsigned64 divisor = (unsigned32)(*rB);
1646 XER |= (xer_overflow | xer_summary_overflow);
1647 CR0_COMPARE(0, 0, Rc);
1650 unsigned64 quotent = dividend / divisor;
1652 CR0_COMPARE((signed_word)quotent, 0, Rc);
1657 # I.3.3.10 Fixed-Point Compare Instructions
1660 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
1661 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1662 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1663 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1664 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1665 if (!is_64bit_mode && L)
1666 program_interrupt(processor, cia,
1667 illegal_instruction_program_interrupt);
1670 signed_word b = EXTS(SI);
1675 CR_COMPARE(BF, a, b);
1678 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
1679 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1680 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1681 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1682 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1683 if (!is_64bit_mode && L)
1684 program_interrupt(processor, cia,
1685 illegal_instruction_program_interrupt);
1697 CR_COMPARE(BF, a, b);
1700 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
1701 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1702 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1703 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1704 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1705 if (!is_64bit_mode && L)
1706 program_interrupt(processor, cia,
1707 illegal_instruction_program_interrupt);
1710 unsigned_word b = UI;
1712 a = MASKED(*rA, 32, 63);
1715 CR_COMPARE(BF, a, b);
1718 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
1719 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1720 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1721 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
1722 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1723 if (!is_64bit_mode && L)
1724 program_interrupt(processor, cia,
1725 illegal_instruction_program_interrupt);
1730 a = MASKED(*rA, 32, 63);
1731 b = MASKED(*rB, 32, 63);
1737 CR_COMPARE(BF, a, b);
1742 # I.3.3.11 Fixed-Point Trap Instructions
1745 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
1747 program_interrupt(processor, cia,
1748 illegal_instruction_program_interrupt);
1750 signed_word a = *rA;
1751 signed_word b = EXTS(SI);
1752 if ((a < b && TO{0})
1754 || (a == b && TO{2})
1755 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1756 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1758 program_interrupt(processor, cia,
1759 trap_program_interrupt);
1762 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
1763 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1764 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1765 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1766 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1767 signed_word a = EXTENDED(*rA);
1768 signed_word b = EXTS(SI);
1769 if ((a < b && TO{0})
1771 || (a == b && TO{2})
1772 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1773 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1775 program_interrupt(processor, cia,
1776 trap_program_interrupt);
1778 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
1780 program_interrupt(processor, cia,
1781 illegal_instruction_program_interrupt);
1783 signed_word a = *rA;
1784 signed_word b = *rB;
1785 if ((a < b && TO{0})
1787 || (a == b && TO{2})
1788 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1789 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1791 program_interrupt(processor, cia,
1792 trap_program_interrupt);
1795 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
1796 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1797 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1798 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
1799 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1800 signed_word a = EXTENDED(*rA);
1801 signed_word b = EXTENDED(*rB);
1802 if (TO == 12 && rA == rB) {
1803 ITRACE(trace_breakpoint, ("breakpoint\n"));
1804 cpu_halt(processor, cia, was_trap, 0);
1806 else if ((a < b && TO{0})
1808 || (a == b && TO{2})
1809 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1810 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1812 program_interrupt(processor, cia,
1813 trap_program_interrupt);
1816 # I.3.3.12 Fixed-Point Logical Instructions
1819 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
1820 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1821 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1822 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1823 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1825 CR0_COMPARE(*rA, 0, 1/*Rc*/);
1827 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
1828 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1829 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1830 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1831 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1832 *rA = *rS & (UI << 16);
1833 CR0_COMPARE(*rA, 0, 1/*Rc*/);
1835 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
1836 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1837 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1838 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1839 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1842 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
1843 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1844 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1845 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1846 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1847 *rA = *rS | (UI << 16);
1849 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
1850 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1851 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1852 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1853 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1856 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
1857 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1858 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1859 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1860 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1861 *rA = *rS ^ (UI << 16);
1863 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
1864 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1865 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1866 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1867 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1869 CR0_COMPARE(*rA, 0, Rc);
1871 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
1872 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1873 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1874 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1875 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1877 CR0_COMPARE(*rA, 0, Rc);
1879 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
1880 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1881 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1882 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1883 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1885 CR0_COMPARE(*rA, 0, Rc);
1887 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
1888 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1889 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1890 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1891 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1893 CR0_COMPARE(*rA, 0, Rc);
1895 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
1896 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1897 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1898 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1899 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1901 CR0_COMPARE(*rA, 0, Rc);
1903 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
1904 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1905 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1906 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1907 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1908 # *rA = ~(*rS ^ *rB); /* A === B */
1909 # CR0_COMPARE(*rA, 0, Rc);
1911 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
1912 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1913 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1914 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1915 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1917 CR0_COMPARE(*rA, 0, Rc);
1918 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
1919 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1920 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1921 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1922 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1924 CR0_COMPARE(*rA, 0, Rc);
1926 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
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 = (signed_word)(signed8)*rS;
1932 CR0_COMPARE(*rA, 0, Rc);
1934 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
1935 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1936 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1937 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1938 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1939 *rA = (signed_word)(signed16)*rS;
1940 CR0_COMPARE(*rA, 0, Rc);
1942 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
1943 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1944 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1945 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1946 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1947 # *rA = (signed_word)(signed32)*rS;
1948 # CR0_COMPARE(*rA, 0, Rc);
1950 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
1952 # unsigned64 mask = BIT64(0);
1953 # unsigned64 source = *rS;
1954 # while (!(source & mask) && mask != 0) {
1959 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
1961 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
1962 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1963 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1964 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1965 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1967 unsigned32 mask = BIT32(0);
1968 unsigned32 source = *rS;
1969 while (!(source & mask) && mask != 0) {
1974 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
1978 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
1981 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
1982 # long n = (sh_5 << 4) | sh_0_4;
1983 # unsigned_word r = ROTL64(*rS, n);
1984 # long b = (mb_5 << 4) | mb_0_4;
1985 # unsigned_word m = MASK(b, 63);
1986 # signed_word result = r & m;
1988 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
1990 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
1991 # long n = (sh_5 << 4) | sh_0_4;
1992 # unsigned_word r = ROTL64(*rS, n);
1993 # long e = (me_5 << 4) | me_0_4;
1994 # unsigned_word m = MASK(0, e);
1995 # signed_word result = r & m;
1997 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
1999 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
2000 # long n = (sh_5 << 4) | sh_0_4;
2001 # unsigned_word r = ROTL64(*rS, n);
2002 # long b = (mb_5 << 4) | mb_0_4;
2003 # unsigned_word m = MASK(0, (64-n));
2004 # signed_word result = r & m;
2006 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2008 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2009 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2010 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2011 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2012 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2015 unsigned32 r = ROTL32(s, n);
2016 unsigned32 m = MASK(MB+32, ME+32);
2017 signed_word result = r & m;
2019 CR0_COMPARE(result, 0, Rc);
2021 ("n=%d, s=0x%x, r=0x%x, m=0x%x, result=0x%x, cr=0x%x\n",
2022 n, s, r, m, result, CR));
2024 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2025 # long n = MASKED(*rB, 58, 63);
2026 # unsigned_word r = ROTL64(*rS, n);
2027 # long b = (mb_5 << 4) | mb_0_4;
2028 # unsigned_word m = MASK(b, 63);
2029 # signed_word result = r & m;
2031 # CR0_COMPARE(result, 0, Rc);
2033 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2034 # long n = MASKED(*rB, 58, 63);
2035 # unsigned_word r = ROTL64(*rS, n);
2036 # long e = (me_5 << 4) | me_0_4;
2037 # unsigned_word m = MASK(0, e);
2038 # signed_word result = r & m;
2040 # CR0_COMPARE(result, 0, Rc);
2042 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2043 # long n = MASKED(*rB, 59, 63);
2044 # unsigned32 r = ROTL32(*rS, n);
2045 # unsigned32 m = MASK(MB+32, ME+32);
2046 # signed_word result = r & m;
2048 # CR0_COMPARE(result, 0, Rc);
2050 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
2051 # long n = (sh_5 << 4) | sh_0_4;
2052 # unsigned_word r = ROTL64(*rS, n);
2053 # long b = (mb_5 << 4) | mb_0_4;
2054 # unsigned_word m = MASK(b, (64-n));
2055 # signed_word result = (r & m) | (*rA & ~m)
2057 # CR0_COMPARE(result, 0, Rc);
2059 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2060 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2061 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2062 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2063 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2065 unsigned32 r = ROTL32(*rS, n);
2066 unsigned32 m = MASK(MB+32, ME+32);
2067 signed_word result = (r & m) | (*rA & ~m);
2069 ITRACE(trace_alu, (": n=%d *rS=0x%x r=0x%x m=0x%x result=0x%x\n",
2070 n, *rS, r, m, result));
2071 CR0_COMPARE(result, 0, Rc);
2074 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2076 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2077 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2078 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2079 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2080 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2081 int n = MASKED(*rB, 59, 63);
2082 unsigned32 source = *rS;
2083 signed_word shifted;
2085 shifted = (source << n);
2089 CR0_COMPARE(shifted, 0, Rc);
2091 ("n=%d, source=0x%x, shifted=0x%x\n",
2092 n, source, shifted));
2094 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
2096 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
2097 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2098 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2099 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2100 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2101 int n = MASKED(*rB, 59, 63);
2102 unsigned32 source = *rS;
2103 signed_word shifted;
2105 shifted = (source >> n);
2109 CR0_COMPARE(shifted, 0, Rc);
2111 ("n=%d, source=0x%x, shifted=0x%x\n",
2112 n, source, shifted));
2114 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
2116 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
2117 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2118 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2119 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2120 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2122 signed_word r = ROTL32(*rS, /*64*/32-n);
2123 signed_word m = MASK(n+32, 63);
2124 int S = MASKED(*rS, 32, 32);
2125 signed_word shifted = (r & m) | (S ? ~m : 0);
2127 if (S && ((r & ~m) & MASK(32, 63)) != 0)
2131 CR0_COMPARE(shifted, 0, Rc);
2133 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
2135 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
2136 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2137 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2138 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2139 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2140 int n = MASKED(*rB, 58, 63);
2141 int shift = (n >= 31 ? 31 : n);
2142 signed32 source = (signed32)*rS; /* signed to keep sign bit */
2143 signed32 shifted = source >> shift;
2144 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
2145 *rA = (signed_word)shifted; /* if 64bit will sign extend */
2146 if (source < 0 && (source & mask))
2150 CR0_COMPARE(shifted, 0, Rc);
2154 # I.3.3.14 Move to/from System Register Instructions
2157 0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
2158 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2159 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2160 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2161 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
2162 int n = (spr{5:9} << 5) | spr{0:4};
2163 if (spr{0} && IS_PROBLEM_STATE(processor))
2164 program_interrupt(processor, cia,
2165 privileged_instruction_program_interrupt);
2166 else if (!spr_is_valid(n)
2167 || spr_is_readonly(n))
2168 program_interrupt(processor, cia,
2169 illegal_instruction_program_interrupt);
2171 spreg new_val = (spr_length(n) == 64
2173 : MASKED(*rS, 32, 63));
2174 /* HACK - time base registers need to be updated immediatly */
2175 if (WITH_TIME_BASE) {
2179 cpu_set_time_base(processor,
2180 (MASKED64(cpu_get_time_base(processor), 32, 63)
2181 | INSERTED64(new_val, 0, 31)));
2184 cpu_set_time_base(processor,
2185 (MASKED64(cpu_get_time_base(processor), 0, 31)
2186 | INSERTED64(new_val, 32, 63)));
2189 cpu_set_decrementer(processor, new_val);
2201 0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
2202 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2203 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2204 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2205 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2206 int n = (spr{5:9} << 5) | spr{0:4};
2207 if (spr{0} && IS_PROBLEM_STATE(processor))
2208 program_interrupt(processor, cia,
2209 privileged_instruction_program_interrupt);
2210 else if (!spr_is_valid(n))
2211 program_interrupt(processor, cia,
2212 illegal_instruction_program_interrupt);
2214 /* HACK - some SPR's need to get their value extracted specially */
2218 # FIXME: 604 uses SCIU{1,2} if only one bit is being set
2219 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
2220 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2221 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2222 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2223 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
2228 unsigned_word mask = 0;
2230 for (f = 0; f < 8; f++) {
2231 if (FXM & (0x80 >> f))
2232 mask |= (0xf << 4*(7-f));
2234 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
2237 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
2239 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
2240 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2241 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2242 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2243 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2244 *rT = (unsigned32)CR;
2247 # I.4.6.2 Floating-Point Load Instructions
2250 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
2251 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2252 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2253 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2254 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2260 *frT = DOUBLE(MEM(unsigned, EA, 4));
2262 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
2263 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2264 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2265 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2266 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2272 *frT = DOUBLE(MEM(unsigned, EA, 4));
2274 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
2275 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2276 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2277 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2278 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2281 program_interrupt(processor, cia,
2282 illegal_instruction_program_interrupt);
2284 *frT = DOUBLE(MEM(unsigned, EA, 4));
2287 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
2288 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2289 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2290 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2291 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2294 program_interrupt(processor, cia,
2295 illegal_instruction_program_interrupt);
2297 *frT = DOUBLE(MEM(unsigned, EA, 4));
2300 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
2301 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2302 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2303 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2304 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2310 *frT = MEM(unsigned, EA, 8);
2312 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
2313 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2314 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2315 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2316 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2322 *frT = MEM(unsigned, EA, 8);
2324 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
2325 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2326 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2327 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2328 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2331 program_interrupt(processor, cia,
2332 illegal_instruction_program_interrupt);
2334 *frT = MEM(unsigned, EA, 8);
2337 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
2338 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2339 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2340 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2341 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2344 program_interrupt(processor, cia,
2345 illegal_instruction_program_interrupt);
2347 *frT = MEM(unsigned, EA, 8);
2352 # I.4.6.3 Floating-Point Store Instructions
2355 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
2356 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2357 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2358 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2359 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2365 STORE(EA, 4, SINGLE(*frS));
2367 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
2368 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2369 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2370 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2371 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2377 STORE(EA, 4, SINGLE(*frS));
2379 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
2380 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2381 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2382 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2383 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2386 program_interrupt(processor, cia,
2387 illegal_instruction_program_interrupt);
2389 STORE(EA, 4, SINGLE(*frS));
2392 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
2393 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2394 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2395 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2396 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2399 program_interrupt(processor, cia,
2400 illegal_instruction_program_interrupt);
2402 STORE(EA, 4, SINGLE(*frS));
2405 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
2406 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2407 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2408 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2409 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2417 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
2418 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2419 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2420 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2421 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2429 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
2430 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2431 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2432 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2433 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2436 program_interrupt(processor, cia,
2437 illegal_instruction_program_interrupt);
2442 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
2443 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2444 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2445 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2446 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2449 program_interrupt(processor, cia,
2450 illegal_instruction_program_interrupt);
2457 # I.4.6.4 Floating-Point Move Instructions
2460 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
2461 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2462 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2463 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2464 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2468 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
2469 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2470 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2471 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2472 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2473 *frT = *frB ^ BIT64(0);
2476 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
2477 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2478 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2479 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2480 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2481 *frT = *frB & ~BIT64(0);
2484 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
2485 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2486 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2487 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2488 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2489 *frT = *frB | BIT64(0);
2495 # I.4.6.5 Floating-Point Arithmetic Instructions
2498 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
2499 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2500 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2501 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2502 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2504 if (is_invalid_operation(processor, cia,
2506 fpscr_vxsnan | fpscr_vxisi,
2509 invalid_arithemetic_operation(processor, cia,
2511 0, /*instruction_is_frsp*/
2512 0, /*instruction_is_convert_to_64bit*/
2513 0, /*instruction_is_convert_to_32bit*/
2514 0); /*single-precision*/
2518 double s = *(double*)frA + *(double*)frB;
2523 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
2524 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2525 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2526 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2527 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2529 if (is_invalid_operation(processor, cia,
2531 fpscr_vxsnan | fpscr_vxisi,
2534 invalid_arithemetic_operation(processor, cia,
2536 0, /*instruction_is_frsp*/
2537 0, /*instruction_is_convert_to_64bit*/
2538 0, /*instruction_is_convert_to_32bit*/
2539 1); /*single-precision*/
2543 float s = *(double*)frA + *(double*)frB;
2548 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
2549 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2550 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2551 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2552 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2554 if (is_invalid_operation(processor, cia,
2556 fpscr_vxsnan | fpscr_vxisi,
2559 invalid_arithemetic_operation(processor, cia,
2561 0, /*instruction_is_frsp*/
2562 0, /*instruction_is_convert_to_64bit*/
2563 0, /*instruction_is_convert_to_32bit*/
2564 0); /*single-precision*/
2568 double s = *(double*)frA - *(double*)frB;
2573 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
2574 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2575 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2576 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2577 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2579 if (is_invalid_operation(processor, cia,
2581 fpscr_vxsnan | fpscr_vxisi,
2584 invalid_arithemetic_operation(processor, cia,
2586 0, /*instruction_is_frsp*/
2587 0, /*instruction_is_convert_to_64bit*/
2588 0, /*instruction_is_convert_to_32bit*/
2589 1); /*single-precision*/
2593 float s = *(double*)frA - *(double*)frB;
2598 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
2599 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2600 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2601 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2602 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2604 if (is_invalid_operation(processor, cia,
2606 fpscr_vxsnan | fpscr_vximz,
2609 invalid_arithemetic_operation(processor, cia,
2611 0, /*instruction_is_frsp*/
2612 0, /*instruction_is_convert_to_64bit*/
2613 0, /*instruction_is_convert_to_32bit*/
2614 0); /*single-precision*/
2618 double s = *(double*)frA * *(double*)frC;
2623 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
2624 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2625 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2626 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2627 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2629 if (is_invalid_operation(processor, cia,
2631 fpscr_vxsnan | fpscr_vximz,
2634 invalid_arithemetic_operation(processor, cia,
2636 0, /*instruction_is_frsp*/
2637 0, /*instruction_is_convert_to_64bit*/
2638 0, /*instruction_is_convert_to_32bit*/
2639 1); /*single-precision*/
2643 float s = *(double*)frA * *(double*)frC;
2648 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
2649 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
2650 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
2651 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
2652 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
2654 if (is_invalid_operation(processor, cia,
2656 fpscr_vxsnan | fpscr_vxzdz,
2659 invalid_arithemetic_operation(processor, cia,
2661 0, /*instruction_is_frsp*/
2662 0, /*instruction_is_convert_to_64bit*/
2663 0, /*instruction_is_convert_to_32bit*/
2664 0); /*single-precision*/
2668 double s = *(double*)frA / *(double*)frB;
2673 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
2674 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
2675 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
2676 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
2677 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
2679 if (is_invalid_operation(processor, cia,
2681 fpscr_vxsnan | fpscr_vxzdz,
2684 invalid_arithemetic_operation(processor, cia,
2686 0, /*instruction_is_frsp*/
2687 0, /*instruction_is_convert_to_64bit*/
2688 0, /*instruction_is_convert_to_32bit*/
2689 1); /*single-precision*/
2693 float s = *(double*)frA / *(double*)frB;
2698 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
2699 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2700 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2701 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2702 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2704 double product; /*HACK! - incorrectly loosing precision ... */
2705 /* compute the multiply */
2706 if (is_invalid_operation(processor, cia,
2708 fpscr_vxsnan | fpscr_vximz,
2711 invalid_arithemetic_operation(processor, cia,
2712 (unsigned64*)&product, *frA, 0, *frC,
2713 0, /*instruction_is_frsp*/
2714 0, /*instruction_is_convert_to_64bit*/
2715 0, /*instruction_is_convert_to_32bit*/
2716 0); /*single-precision*/
2720 product = *(double*)frA * *(double*)frC;
2722 /* compute the add */
2723 if (is_invalid_operation(processor, cia,
2725 fpscr_vxsnan | fpscr_vxisi,
2728 invalid_arithemetic_operation(processor, cia,
2729 frT, product, *frB, 0,
2730 0, /*instruction_is_frsp*/
2731 0, /*instruction_is_convert_to_64bit*/
2732 0, /*instruction_is_convert_to_32bit*/
2733 0); /*single-precision*/
2737 double s = product + *(double*)frB;
2742 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
2743 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2744 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2745 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2746 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2748 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
2749 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2750 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2751 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2752 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2754 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
2755 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2756 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2757 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2758 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2760 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
2761 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2762 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2763 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2764 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2766 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
2767 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2768 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2769 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2770 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2772 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
2773 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
2774 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2775 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
2776 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2778 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
2779 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2780 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2781 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2782 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2786 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
2789 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
2790 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
2791 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2792 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2793 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
2796 unsigned64 frac_grx;
2797 /* split off cases for what to do */
2798 if (EXTRACTED64(*frB, 1, 11) < 897
2799 && EXTRACTED64(*frB, 1, 63) > 0) {
2800 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
2801 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
2803 if (EXTRACTED64(*frB, 1, 11) > 1150
2804 && EXTRACTED64(*frB, 1, 11) < 2047) {
2805 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
2806 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
2808 if (EXTRACTED64(*frB, 1, 11) > 896
2809 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
2810 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
2811 if (EXTRACTED64(*frB, 1, 11) == 2047) {
2812 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
2813 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
2814 if (EXTRACTED64(*frB, 12, 12) == 0
2815 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
2818 Disabled_Exponent_Underflow:
2819 sign = EXTRACTED64(*frB, 0, 0);
2820 if (EXTRACTED64(*frB, 1, 11) == 0) {
2822 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2824 if (EXTRACTED64(*frB, 1, 11) > 0) {
2825 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2826 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2828 Denormalize_Operand:
2829 /* G|R|X == zero from above */
2830 while (exp < -126) {
2832 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
2833 | MASKED64(frac_grx, 55, 55));
2835 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
2836 Round_Single(processor, sign, &exp, &frac_grx);
2837 FPSCR_SET_XX(FPSCR & fpscr_fi);
2838 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
2839 *frT = INSERTED64(sign, 0, 0);
2840 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
2841 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
2843 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
2844 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
2845 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2846 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2848 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
2849 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
2850 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
2852 /*Normalize_Operand:*/
2853 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
2855 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
2857 *frT = (INSERTED64(sign, 0, 0)
2858 | INSERTED64(exp + 1023, 1, 11)
2859 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2862 Enabled_Exponent_Underflow:
2864 sign = EXTRACTED64(*frB, 0, 0);
2865 if (EXTRACTED64(*frB, 1, 11) == 0) {
2867 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2869 if (EXTRACTED64(*frB, 1, 11) > 0) {
2870 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2871 frac_grx = (BIT64(0) |
2872 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
2874 /*Normalize_Operand:*/
2875 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
2877 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
2879 Round_Single(processor, sign, &exp, &frac_grx);
2880 FPSCR_SET_XX(FPSCR & fpscr_fi);
2882 *frT = (INSERTED64(sign, 0, 0)
2883 | INSERTED64(exp + 1023, 1, 11)
2884 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2885 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2886 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2888 Disabled_Exponent_Overflow:
2890 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
2891 if (EXTRACTED64(*frB, 0, 0) == 0) {
2892 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
2893 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
2895 if (EXTRACTED64(*frB, 0, 0) == 1) {
2896 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
2897 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
2900 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
2901 if (EXTRACTED64(*frB, 0, 0) == 0) {
2902 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
2903 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2905 if (EXTRACTED64(*frB, 0, 0) == 1) {
2906 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
2907 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2910 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
2911 if (EXTRACTED64(*frB, 0, 0) == 0) {
2912 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
2913 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
2915 if (EXTRACTED64(*frB, 0, 0) == 1) {
2916 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
2917 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2920 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
2921 if (EXTRACTED64(*frB, 0, 0) == 0) {
2922 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
2923 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2925 if (EXTRACTED64(*frB, 0, 0) == 1) {
2926 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
2927 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
2930 /* FPSCR[FR] <- undefined */
2934 Enabled_Exponent_Overflow:
2935 sign = EXTRACTED64(*frB, 0, 0);
2936 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2937 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2938 Round_Single(processor, sign, &exp, &frac_grx);
2939 FPSCR_SET_XX(FPSCR & fpscr_fi);
2943 *frT = (INSERTED64(sign, 0, 0)
2944 | INSERTED64(exp + 1023, 1, 11)
2945 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2946 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2947 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2951 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
2952 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
2958 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
2959 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
2964 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
2965 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
2970 FPSCR_OR_VX(fpscr_vxsnan);
2971 if ((FPSCR & fpscr_ve) == 0) {
2972 *frT = (MASKED64(*frB, 0, 11)
2974 | MASKED64(*frB, 13, 34));
2975 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
2981 sign = EXTRACTED64(*frB, 0, 0);
2982 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2983 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2984 Round_Single(processor, sign, &exp, &frac_grx);
2985 FPSCR_SET_XX(FPSCR & fpscr_fi);
2986 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
2987 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
2988 *frT = (INSERTED64(sign, 0, 0)
2989 | INSERTED64(exp + 1023, 1, 11)
2990 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2991 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2992 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2996 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
2998 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
3000 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
3002 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
3003 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3004 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3005 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3006 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3008 convert_to_integer(processor, cia,
3010 fpscr_rn_round_towards_zero, 32);
3013 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
3014 int sign = EXTRACTED64(*frB, 0, 0);
3016 unsigned64 frac = *frB;
3017 if (frac == 0) goto Zero_Operand;
3018 if (sign == 1) frac = ~frac + 1;
3019 while (EXTRACTED64(frac, 0, 0) == 0) {
3020 /*??? do the loop 0 times if (FRB) = max negative integer */
3021 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
3024 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
3025 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3026 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3027 *frT = (INSERTED64(sign, 0, 0)
3028 | INSERTED64(exp + 1023, 1, 11)
3029 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
3035 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3042 # I.4.6.7 Floating-Point Compare Instructions
3045 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
3046 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3047 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3048 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3049 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3052 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3053 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3054 else if (is_less_than(frA, frB))
3055 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3056 else if (is_greater_than(frA, frB))
3057 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3059 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3061 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3062 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
3063 FPSCR_OR_VX(fpscr_vxsnan);
3066 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
3067 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3068 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3069 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3070 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3073 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3074 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3075 else if (is_less_than(frA, frB))
3076 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3077 else if (is_greater_than(frA, frB))
3078 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3080 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3082 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3083 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
3084 FPSCR_OR_VX(fpscr_vxsnan);
3085 if ((FPSCR & fpscr_ve) == 0)
3086 FPSCR_OR_VX(fpscr_vxvc);
3088 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
3089 FPSCR_OR_VX(fpscr_vxvc);
3095 # I.4.6.8 Floating-Point Status and Control Register Instructions
3098 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
3100 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
3102 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
3104 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
3106 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
3108 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
3112 # I.A.1.1 Floating-Point Store Instruction
3114 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
3117 # I.A.1.2 Floating-Point Arithmetic Instructions
3120 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
3122 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
3124 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
3126 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
3129 # I.A.1.3 Floating-Point Select Instruction
3132 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
3136 # II.3.2 Cache Management Instructions
3139 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
3140 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3141 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3142 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3143 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3144 /* blindly flush all instruction cache entries */
3145 #if WITH_IDECODE_CACHE_SIZE
3146 cpu_flush_icache(processor);
3149 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
3150 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3151 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3152 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3153 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3154 cpu_synchronize_context(processor);
3158 # II.3.2.2 Data Cache Instructions
3161 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
3162 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3163 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
3164 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
3165 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3166 TRACE(trace_tbd,("Data Cache Block Touch\n"));
3168 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
3169 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3170 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
3171 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
3172 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3173 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
3175 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
3176 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3177 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, PPC_SERIALIZE
3178 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, PPC_SERIALIZE
3179 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3180 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
3182 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
3183 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3184 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, PPC_SERIALIZE
3185 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, PPC_SERIALIZE
3186 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3187 TRACE(trace_tbd,("Data Cache Block Store\n"));
3189 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
3190 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3191 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, PPC_SERIALIZE
3192 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, PPC_SERIALIZE
3193 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, PPC_SERIALIZE
3194 TRACE(trace_tbd,("Data Cache Block Flush\n"));
3197 # II.3.3 Enforce In-order Execution of I/O Instruction
3200 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
3201 /* Since this model has no instruction overlap
3202 this instruction need do nothing */
3205 # II.4.1 Time Base Instructions
3208 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
3209 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3210 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3211 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3212 int n = (tbr{5:9} << 5) | tbr{0:4};
3214 if (is_64bit_implementation) *rT = TB;
3215 else *rT = EXTRACTED64(TB, 32, 63);
3217 else if (n == 269) {
3218 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
3219 else *rT = EXTRACTED64(TB, 0, 31);
3222 program_interrupt(processor, cia,
3223 illegal_instruction_program_interrupt);
3227 # III.2.3.1 System Linkage Instructions
3230 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
3231 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3232 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3233 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3234 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, PPC_SERIALIZE
3235 if (IS_PROBLEM_STATE(processor)) {
3236 program_interrupt(processor, cia,
3237 privileged_instruction_program_interrupt);
3240 MSR = (MASKED(SRR1, 0, 32)
3241 | MASKED(SRR1, 37, 41)
3242 | MASKED(SRR1, 48, 63));
3243 NIA = MASKED(SRR0, 0, 61);
3244 cpu_synchronize_context(processor);
3248 # III.3.4.1 Move to/from System Register Instructions
3251 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
3252 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
3253 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
3254 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3255 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3256 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3257 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3258 if (IS_PROBLEM_STATE(processor))
3259 program_interrupt(processor, cia,
3260 privileged_instruction_program_interrupt);
3264 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
3265 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3266 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, PPC_SERIALIZE
3267 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, PPC_SERIALIZE
3268 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, PPC_SERIALIZE
3269 if (IS_PROBLEM_STATE(processor))
3270 program_interrupt(processor, cia,
3271 privileged_instruction_program_interrupt);
3277 # III.4.11.1 Cache Management Instructions
3280 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
3281 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, PPC_SERIALIZE
3282 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, PPC_SERIALIZE
3283 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, PPC_SERIALIZE
3284 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, PPC_SERIALIZE
3285 if (IS_PROBLEM_STATE(processor))
3286 program_interrupt(processor, cia,
3287 privileged_instruction_program_interrupt);
3289 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
3292 # III.4.11.2 Segment Register Manipulation Instructions
3295 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
3296 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3297 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3298 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3299 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3300 if (IS_PROBLEM_STATE(processor))
3301 program_interrupt(processor, cia,
3302 privileged_instruction_program_interrupt);
3306 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
3307 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3308 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3309 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, PPC_SERIALIZE
3310 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3311 if (IS_PROBLEM_STATE(processor))
3312 program_interrupt(processor, cia,
3313 privileged_instruction_program_interrupt);
3315 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
3317 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
3318 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3319 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3320 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3321 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3322 if (IS_PROBLEM_STATE(processor))
3323 program_interrupt(processor, cia,
3324 privileged_instruction_program_interrupt);
3328 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
3329 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3330 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3331 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, PPC_SERIALIZE
3332 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, PPC_SERIALIZE
3333 if (IS_PROBLEM_STATE(processor))
3334 program_interrupt(processor, cia,
3335 privileged_instruction_program_interrupt);
3337 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
3341 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
3344 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
3346 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
3348 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
3350 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
3352 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
3356 # III.A.1.2 External Access Instructions
3359 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
3361 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed