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, ppc_insn_bad
70 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, ppc_insn_bad
71 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, ppc_insn_bad
72 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, ppc_insn_bad
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 signed16 issue; /* # cycles before function unit can process other insns */
94 signed16 done; /* # cycles before insn is done */
95 void (*function)(itable_index index, /* function to do actual processing */
96 model_data *model_ptr,
98 idecode_cache *cache_entry,
99 instruction_word instruction,
100 const model_time *const default_time);
104 /* Register mappings */
105 #define PPC_INT_REG 0 /* start of integer registers */
106 #define PPC_FLOAT_REG (PPC_INT_REG + 32) /* start of floating point registers */
107 #define PPC_CR_REG (PPC_FLOAT_REG + 32) /* start of CR0 .. CR7 */
108 #define PPC_SPR_REG (PPC_CR_REG + 8) /* start of special purpose registers */
109 #define PPC_FPSCR_REG (PPC_SPR_REG + 1024) /* start of fpscr register */
110 #define NR_PPC_REGS (PPC_FPSCR_REG + 1) /* # of registers to allocate */
112 /* Structure for each register to indicate whether it is free or not */
113 typedef struct _model_reg model_reg;
115 model_reg *next; /* next register to be released */
116 int in_use; /* non zero if register is used */
119 /* Structure for each functional unit that is busy */
120 typedef struct _model_busy model_busy;
122 model_busy *next; /* next function unit */
123 model_reg *reg; /* list of registers to release */
124 ppc_function_unit unit; /* function unit name */
125 signed16 issue; /* # of cycles until unit can accept another insn */
126 signed16 done; /* # of cycles until insn is done */
129 /* Structure to hold the current state information for the simulated CPU model */
131 cpu *processor; /* point back to processor */
132 const char *name; /* model name */
133 const model_time *timing; /* timing information */
134 model_busy *busy_list; /* list of busy function units */
135 model_busy *free_list; /* list of model_busy structs not in use */
136 model_reg registers[NR_PPC_REGS]; /* register status */
137 unsigned32 busy_mask; /* bitmask of busy function units */
138 count_type nr_cycles; /* # cycles */
139 count_type nr_branches; /* # branches */
140 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
141 count_type nr_branch_predict_trues; /* # branches predicted correctly */
142 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
143 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
146 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
147 "unknown functional unit instruction",
148 "integer functional unit instruction",
149 "system register functional unit instruction",
150 "1st single cycle integer functional unit instruction",
151 "2nd single cycle integer functional unit instruction",
152 "multiple cycle integer functional unit instruction",
153 "floating point functional unit instruction",
154 "load/store functional unit instruction",
155 "branch functional unit instruction",
158 # Advance state to next cycle, releasing any registers allocated
159 void::model-internal::model_new_cycle:model_data *model_ptr
160 model_busy *cur_busy = model_ptr->busy_list;
161 model_busy *free_list = model_ptr->free_list;
162 model_busy *next_busy = (model_busy *)0;
163 unsigned32 busy_mask = model_ptr->busy_mask;
166 model_ptr->nr_cycles++;
167 for ( ; cur_busy; cur_busy = next) {
168 next = cur_busy->next;
169 if (--cur_busy->done <= 0) { /* function unit done, release registers */
170 model_reg *reg = cur_busy->reg;
171 TRACE(trace_model,("done, retiring %s\n", ppc_function_unit_name[cur_busy->unit]));
173 TRACE(trace_model,("freeing up reg, address 0x%lx (%d)\n", (long)reg, reg - &model_ptr->registers[0]));
177 busy_mask &= ~(1 << cur_busy->unit);
178 cur_busy->next = free_list;
179 free_list = cur_busy;
181 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
182 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
183 busy_mask &= ~(1 << cur_busy->unit);
184 cur_busy->next = next_busy;
185 next_busy = cur_busy;
188 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
189 ppc_function_unit_name[cur_busy->unit],
192 cur_busy->next = next_busy;
193 next_busy = cur_busy;
197 model_ptr->busy_list = next_busy;
198 model_ptr->free_list = free_list;
199 model_ptr->busy_mask = busy_mask;
201 # Mark a function unit as busy, return the busy structure so regs can be added to be released
202 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
205 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
207 if (!model_ptr->free_list) {
208 busy = ZALLOC(model_busy);
211 busy = model_ptr->free_list;
212 model_ptr->free_list = busy->next;
213 busy->reg = (model_reg *)0;
215 busy->next = model_ptr->busy_list;
219 model_ptr->busy_list = busy;
222 # Signal an instruction this model doesn't support
223 void::model-internal::ppc_insn_bad:itable_index index, model_data *model_ptr, unsigned_word cia, idecode_cache *cache_entry, instruction_word instruction, const model_time *const default_time
224 program_interrupt(model_ptr->processor, cia,
225 illegal_instruction_program_interrupt);
227 # Branch instruction, always end the current cycle
228 void::model-internal::ppc_insn_branch:itable_index index, model_data *model_ptr, unsigned_word cia, idecode_cache *cache_entry, instruction_word instruction, const model_time *const default_time
229 model_ptr->nr_units[PPC_UNIT_BPU]++;
230 model_new_cycle(model_ptr);
232 # Generic instruction, right now schedule, but don't worry about data dependencies
233 void::model-internal::ppc_insn_generic:itable_index index, model_data *model_ptr, unsigned_word cia, idecode_cache *cache_entry, instruction_word instruction, const model_time *const default_time
234 ppc_function_unit first_unit = default_time->first_unit;
235 ppc_function_unit last_unit = default_time->last_unit;
236 ppc_function_unit unit;
239 unsigned32 busy_mask = model_ptr->busy_mask;
240 for (unit = first_unit; unit <= last_unit; unit++) {
241 if (((1 << unit) & busy_mask) == 0) {
242 (void) model_make_busy(model_ptr, unit,
243 model_ptr->timing[index].issue,
244 model_ptr->timing[index].done);
246 model_ptr->busy_mask |= (1 << unit);
247 model_ptr->nr_units[unit]++;
251 model_new_cycle(model_ptr);
254 model_data *::model-function::model_create:cpu *processor
255 model_data *model_ptr = ZALLOC(model_data);
256 ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
257 model_ptr->name = model_name[CURRENT_MODEL];
258 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
259 model_ptr->processor = processor;
260 model_ptr->nr_cycles = 1;
263 void::model-function::model_init:model_data *model_ptr
265 void::model-function::model_halt:model_data *model_ptr
266 /* Let pipeline drain */
267 while (model_ptr->busy_list)
268 model_new_cycle(model_ptr);
270 void::model-function::model_issue:itable_index index, model_data *model_ptr, unsigned_word cia, idecode_cache *cache_entry, instruction_word instruction
271 const model_time *const default_time = &model_ptr->timing[(int)index];
272 (*default_time->function)(index, model_ptr, cia, cache_entry, instruction, default_time);
274 model_print *::model-function::model_mon_info:model_data *model_ptr
279 head = tail = ZALLOC(model_print);
280 tail->count = model_ptr->nr_cycles;
281 tail->name = "cycle";
282 tail->suffix_plural = "s";
283 tail->suffix_singular = "";
285 if (model_ptr->nr_branches) {
286 tail->next = ZALLOC(model_print);
288 tail->count = model_ptr->nr_branches;
289 tail->name = "branch";
290 tail->suffix_plural = "es";
291 tail->suffix_singular = "";
294 if (model_ptr->nr_branches_fallthrough) {
295 tail->next = ZALLOC(model_print);
297 tail->count = model_ptr->nr_branches_fallthrough;
298 tail->name = "conditional branch";
299 tail->suffix_plural = "es fell through";
300 tail->suffix_singular = " fell through";
303 if (model_ptr->nr_branch_predict_trues) {
304 tail->next = ZALLOC(model_print);
306 tail->count = model_ptr->nr_branch_predict_trues;
307 tail->name = "successful branch prediction";
308 tail->suffix_plural = "s";
309 tail->suffix_singular = "";
312 if (model_ptr->nr_branch_predict_falses) {
313 tail->next = ZALLOC(model_print);
315 tail->count = model_ptr->nr_branch_predict_falses;
316 tail->name = "unsuccessful branch prediction";
317 tail->suffix_plural = "s";
318 tail->suffix_singular = "";
321 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
322 if (model_ptr->nr_units[i]) {
323 tail->next = ZALLOC(model_print);
325 tail->count = model_ptr->nr_units[i];
326 tail->name = ppc_function_unit_name[i];
327 tail->suffix_plural = "s";
328 tail->suffix_singular = "";
332 tail->next = (model_print *)0;
335 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
344 void::model-function::model_branches:model_data *model_ptr, int failed
346 model_ptr->nr_branches_fallthrough++;
348 model_ptr->nr_branches++;
350 void::model-function::model_branch_predict:model_data *model_ptr, int success
352 model_ptr->nr_branch_predict_trues++;
354 model_ptr->nr_branch_predict_falses++;
356 # The following (illegal) instruction is `known' by gen and is
357 # called when ever an illegal instruction is encountered
359 program_interrupt(processor, cia,
360 illegal_instruction_program_interrupt);
364 # The following (floating point unavailable) instruction is `known' by gen
365 # and is called when ever an a floating point instruction is to be
366 # executed but floating point is make unavailable by the MSR
367 ::internal::floating_point_unavailable
368 floating_point_unavailable_interrupt(processor, cia);
373 # Floating point support functions
376 # Convert 32bit single to 64bit double
377 unsigned64::function::DOUBLE:unsigned32 WORD
379 if (EXTRACTED32(WORD, 1, 8) > 0
380 && EXTRACTED32(WORD, 1, 8) < 255) {
381 /* normalized operand */
382 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
383 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
384 | INSERTED64(not_word_1_1, 2, 2)
385 | INSERTED64(not_word_1_1, 3, 3)
386 | INSERTED64(not_word_1_1, 4, 4)
387 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
389 else if (EXTRACTED32(WORD, 1, 8) == 0
390 && EXTRACTED32(WORD, 9, 31) != 0) {
391 /* denormalized operand */
392 int sign = EXTRACTED32(WORD, 0, 0);
394 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
395 /* normalize the operand */
396 while (MASKED64(frac, 0, 0) == 0) {
400 FRT = (INSERTED64(sign, 0, 0)
401 | INSERTED64(exp + 1023, 1, 11)
402 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
404 else if (EXTRACTED32(WORD, 1, 8) == 255
405 || EXTRACTED32(WORD, 1, 31) == 0) {
406 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
407 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
408 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
409 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
410 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
413 error("DOUBLE - unknown case\n");
418 # Convert 64bit single to 32bit double
419 unsigned32::function::SINGLE:unsigned64 FRS
421 if (EXTRACTED64(FRS, 1, 11) > 896
422 || EXTRACTED64(FRS, 1, 63) == 0) {
423 /* no denormalization required (includes Zero/Infinity/NaN) */
424 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
425 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
427 else if (874 <= EXTRACTED64(FRS, 1, 11)
428 && EXTRACTED64(FRS, 1, 11) <= 896) {
429 /* denormalization required */
430 int sign = EXTRACTED64(FRS, 0, 0);
431 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
432 unsigned64 frac = (BIT64(0)
433 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
434 /* denormalize the operand */
436 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
439 WORD = (INSERTED32(sign, 0, 0)
440 | INSERTED32(0x00, 1, 8)
441 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
444 WORD = 0x0; /* ??? */
449 # round 64bit double to 64bit but single
450 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
451 /* comparisons ignore u bits */
454 int lsb = EXTRACTED64(*frac_grx, 23, 23);
455 int gbit = EXTRACTED64(*frac_grx, 24, 24);
456 int rbit = EXTRACTED64(*frac_grx, 25, 25);
457 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
458 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
459 if (lsb == 1 && gbit == 1) inc = 1;
460 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
461 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
463 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
464 if (sign == 0 && gbit == 1) inc = 1;
465 if (sign == 0 && rbit == 1) inc = 1;
466 if (sign == 0 && xbit == 1) inc = 1;
468 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
469 if (sign == 1 && gbit == 1) inc = 1;
470 if (sign == 1 && rbit == 1) inc = 1;
471 if (sign == 1 && xbit == 1) inc = 1;
473 /* work out addition in low 25 bits of out */
474 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
475 *frac_grx = INSERTED64(out, 0, 23);
476 if (out & BIT64(64 - 23 - 1 - 1)) {
477 *frac_grx = (BIT64(0) |
478 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
481 /* frac_grx[24:52] = 0 already */
483 FPSCR_SET_FI(gbit || rbit || xbit);
487 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
489 if (round_mode == fpscr_rn_round_to_nearest) {
490 if (*frac64 == 1 && gbit == 1) inc = 1;
491 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
492 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
494 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
495 if (sign == 0 && gbit == 1) inc = 1;
496 if (sign == 0 && rbit == 1) inc = 1;
497 if (sign == 0 && xbit == 1) inc = 1;
499 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
500 if (sign == 1 && gbit == 1) inc = 1;
501 if (sign == 1 && rbit == 1) inc = 1;
502 if (sign == 1 && xbit == 1) inc = 1;
504 /* frac[0:64] = frac[0:64} + inc */
505 *frac += (*frac64 && inc ? 1 : 0);
506 *frac64 = (*frac64 + inc) & 0x1;
508 FPSCR_SET_FI(gbit | rbit | xbit);
511 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
514 int lsb = EXTRACTED64(*frac, 52, 52);
515 int gbit = EXTRACTED64(*frac, 53, 53);
516 int rbit = EXTRACTED64(*frac, 54, 54);
517 int xbit = EXTRACTED64(*frac, 55, 55);
518 if (round_mode == fpscr_rn_round_to_nearest) {
519 if (lsb == 1 && gbit == 1) inc = 1;
520 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
521 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
523 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
524 if (sign == 0 && gbit == 1) inc = 1;
525 if (sign == 0 && rbit == 1) inc = 1;
526 if (sign == 0 && xbit == 1) inc = 1;
528 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
529 if (sign == 1 && gbit == 1) inc = 1;
530 if (sign == 1 && rbit == 1) inc = 1;
531 if (sign == 1 && xbit == 1) inc = 1;
533 /* frac//carry_out = frac + inc */
534 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
535 carry_out = EXTRACTED64(*frac, 0, 0);
537 if (carry_out == 1) *exp = *exp + 1;
539 FPSCR_SET_FI(gbit | rbit | xbit);
540 FPSCR_SET_XX(FPSCR & fpscr_fi);
543 # conversion of FP to integer
544 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
552 int sign = EXTRACTED64(frb, 0, 0);
553 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
554 goto Infinity_Operand;
555 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
557 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
559 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
560 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
561 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
562 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
563 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
566 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
567 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
570 gbit = 0, rbit = 0, xbit = 0;
571 for (i = 1; i <= 63 - exp; i++) {
575 frac64 = EXTRACTED64(frac, 63, 63);
576 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
578 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
579 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
582 frac += (frac64 ? 1 : 0);
583 frac64 = (frac64 + 1) & 0x1;
585 if (tgt_precision == 32 /* can ignore frac64 in compare */
586 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
588 if (tgt_precision == 64 /* can ignore frac64 in compare */
589 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
591 if (tgt_precision == 32 /* can ignore frac64 in compare */
592 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
594 if (tgt_precision == 64 /* can ignore frac64 in compare */
595 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
597 FPSCR_SET_XX(FPSCR & fpscr_fi);
598 if (tgt_precision == 32)
599 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
600 if (tgt_precision == 64)
601 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
602 /*FPSCR[fprf] = undefined */
608 FPSCR_OR_VX(fpscr_vxcvi);
609 if ((FPSCR & fpscr_ve) == 0) {
610 if (tgt_precision == 32) {
611 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
612 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
615 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
616 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
618 /* FPSCR[FPRF] = undefined */
625 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
626 if ((FPSCR & fpscr_ve) == 0) {
627 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
628 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
629 /* FPSCR[fprf] = undefined */
636 FPSCR_OR_VX(fpscr_vxcvi);
637 if ((FPSCR & fpscr_ve) == 0) {
638 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
639 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
640 /* FPSCR[fprf] = undefined */
647 FPSCR_OR_VX(fpscr_vxcvi);
648 if ((FPSCR & fpscr_ve) == 0) {
649 if (tgt_precision == 32) {
650 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
651 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
654 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
655 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
657 /* FPSCR[fprf] = undefined */
663 # extract out raw fields of a FP number
664 int::function::sign:unsigned64 FRS
665 return (MASKED64(FRS, 0, 0)
668 int::function::biased_exp:unsigned64 frs, int single
670 return EXTRACTED64(frs, 1, 8);
672 return EXTRACTED64(frs, 1, 11);
673 unsigned64::function::fraction:unsigned64 frs, int single
675 return EXTRACTED64(frs, 9, 31);
677 return EXTRACTED64(frs, 12, 63);
679 # a number?, each of the below return +1 or -1 (based on sign bit)
681 int::function::is_nor:unsigned64 frs, int single
682 int exp = biased_exp(frs, single);
684 && exp <= (single ? 254 : 2046));
685 int::function::is_zero:unsigned64 FRS
686 return (MASKED64(FRS, 1, 63) == 0
689 int::function::is_den:unsigned64 frs, int single
690 int exp = biased_exp(frs, single);
691 unsigned64 frac = fraction(frs, single);
692 return (exp == 0 && frac != 0
695 int::function::is_inf:unsigned64 frs, int single
696 int exp = biased_exp(frs, single);
697 int frac = fraction(frs, single);
698 return (exp == (single ? 255 : 2047) && frac == 0
701 int::function::is_NaN:unsigned64 frs, int single
702 int exp = biased_exp(frs, single);
703 int frac = fraction(frs, single);
704 return (exp == (single ? 255 : 2047) && frac != 0
707 int::function::is_SNaN:unsigned64 frs, int single
708 return (is_NaN(frs, single)
709 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
712 int::function::is_QNaN:unsigned64 frs, int single
713 return (is_NaN(frs, single) && !is_SNaN(frs, single));
714 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
715 return *(double*)fra < *(double*)frb;
716 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
717 return *(double*)fra > *(double*)frb;
718 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
719 return *(double*)fra == *(double*)frb;
722 # which quiet nan should become the result
723 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
725 if (is_NaN(fra, single))
727 else if (is_NaN(frb, single))
728 if (instruction_is_frsp)
729 frt = MASKED64(frb, 0, 34);
732 else if (is_NaN(frc, single))
734 else if (generate_qnan)
735 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
737 error("select_qnan - default reached\n");
741 # detect invalid operation
742 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
744 if ((check & fpscr_vxsnan)
745 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
746 FPSCR_OR_VX(fpscr_vxsnan);
749 if ((check & fpscr_vxisi)
750 && (is_inf(fra, single) && is_inf(frb, single))
751 && ((negate && sign(fra) != sign(frb))
752 || (!negate && sign(fra) == sign(frb)))) {
753 /*FIXME: don't handle inf-inf VS inf+-inf */
754 FPSCR_OR_VX(fpscr_vxisi);
757 if ((check & fpscr_vxidi)
758 && (is_inf(fra, single) && is_inf(frb, single))) {
759 FPSCR_OR_VX(fpscr_vxidi);
762 if ((check & fpscr_vxzdz)
763 && (is_zero(fra) && is_zero(frb))) {
764 FPSCR_OR_VX(fpscr_vxzdz);
767 if ((check & fpscr_vximz)
768 && (is_zero(fra) && is_inf(frb, single))) {
769 FPSCR_OR_VX(fpscr_vximz);
772 if ((check & fpscr_vxvc)
773 && (is_NaN(fra, single) || is_NaN(frb, single))) {
774 FPSCR_OR_VX(fpscr_vxvc);
777 if ((check & fpscr_vxsoft)) {
778 FPSCR_OR_VX(fpscr_vxsoft);
781 if ((check & fpscr_vxsqrt)
783 FPSCR_OR_VX(fpscr_vxsqrt);
786 /* if ((check && fpscr_vxcvi) {
787 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
788 FPSCR_OR_VX(fpscr_vxcvi);
798 # handle case of invalid operation
799 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
800 if (FPSCR & fpscr_ve) {
801 /* invalid operation exception enabled */
805 /* fpscr_FPRF unchanged */
808 /* invalid operation exception disabled */
809 if (instruction_is_convert_to_64bit) {
812 else if (instruction_is_convert_to_32bit) {
815 else { /* arrith, frsp */
816 *frt = select_qnan(fra, frb, frc,
817 instruction_is_frsp, 0/*generate*/, single);
820 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
828 # I.2.4.1 Branch Instructions
830 0.18,6.LI,30.AA,31.LK:I:t::Branch
831 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
832 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
833 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
834 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
835 if (AA) NIA = IEA(EXTS(LI_0b00));
836 else NIA = IEA(CIA + EXTS(LI_0b00));
837 if (LK) LR = (spreg)CIA+4;
838 model_branches(cpu_model(processor), 1);
840 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
841 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
842 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
843 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
844 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
845 int M, ctr_ok, cond_ok, succeed;
846 if (is_64bit_implementation && is_64bit_mode) M = 0;
848 if (!BO{2}) CTR = CTR - 1;
849 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
850 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
851 if (ctr_ok && cond_ok) {
852 if (AA) NIA = IEA(EXTS(BD_0b00));
853 else NIA = IEA(CIA + EXTS(BD_0b00));
858 if (LK) LR = (spreg)IEA(CIA + 4);
859 model_branches(cpu_model(processor), succeed);
862 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
863 reverse = EXTS(BD_0b00) < 0;
864 } else { /* branch prediction bit not set */
865 reverse = EXTS(BD_0b00) >= 0;
867 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
870 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
871 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
872 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
873 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
874 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
875 int M, ctr_ok, cond_ok, succeed;
876 if (is_64bit_implementation && is_64bit_mode) M = 0;
878 if (!BO{2}) CTR = CTR - 1;
879 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
880 cond_ok = BO{0} || (CR{BI} == BO{1});
881 if (ctr_ok && cond_ok) {
887 if (LK) LR = (spreg)IEA(CIA + 4);
888 model_branches(cpu_model(processor), succeed);
890 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
892 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
893 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
894 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
895 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
896 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
897 int cond_ok, succeed;
898 cond_ok = BO{0} || (CR{BI} == BO{1});
905 if (LK) LR = (spreg)IEA(CIA + 4);
906 model_branches(cpu_model(processor), succeed);
908 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
911 # I.2.4.2 System Call Instruction
913 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
914 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
915 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
916 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
917 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
918 system_call_interrupt(processor, cia);
921 # I.2.4.3 Condition Register Logical Instructions
923 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
924 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
925 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
926 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
927 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
928 BLIT32(CR, BT, CR{BA} && CR{BB});
930 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
931 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
932 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
933 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
934 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
935 BLIT32(CR, BT, CR{BA} || CR{BB});
937 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
938 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
939 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
940 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
941 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
942 BLIT32(CR, BT, CR{BA} != CR{BB});
944 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
945 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
946 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
947 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
948 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
949 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
951 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
952 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
953 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
954 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
955 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
956 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
958 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
959 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
960 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
961 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
962 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
963 BLIT32(CR, BT, CR{BA} == CR{BB});
965 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
966 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
967 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
968 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
969 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
970 BLIT32(CR, BT, CR{BA} && !CR{BB});
972 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
973 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
974 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
975 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
976 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
977 BLIT32(CR, BT, CR{BA} || !CR{BB});
980 # I.2.4.4 Condition Register Field Instruction
982 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
983 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
984 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
985 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
986 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
987 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
991 # I.3.3.2 Fixed-Point Load Instructions
994 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
995 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
996 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
997 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
998 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1004 *rT = MEM(unsigned, EA, 1);
1006 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1007 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1008 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1009 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1010 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1016 *rT = MEM(unsigned, EA, 1);
1018 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1019 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1020 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1021 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1022 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1024 if (RA == 0 || RA == RT)
1025 program_interrupt(processor, cia,
1026 illegal_instruction_program_interrupt);
1028 *rT = MEM(unsigned, EA, 1);
1031 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1032 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1033 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1034 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1035 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1037 if (RA == 0 || RA == RT)
1038 program_interrupt(processor, cia,
1039 illegal_instruction_program_interrupt);
1041 *rT = MEM(unsigned, EA, 1);
1044 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1045 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1046 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1047 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1048 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1054 *rT = MEM(unsigned, EA, 2);
1056 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1057 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1058 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1059 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1060 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1066 *rT = MEM(unsigned, EA, 2);
1067 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1068 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1069 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1070 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1071 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1073 if (RA == 0 || RA == RT)
1074 program_interrupt(processor, cia,
1075 illegal_instruction_program_interrupt);
1077 *rT = MEM(unsigned, EA, 2);
1080 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1081 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1082 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1083 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1084 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1086 if (RA == 0 || RA == RT)
1087 program_interrupt(processor, cia,
1088 illegal_instruction_program_interrupt);
1090 *rT = MEM(unsigned, EA, 2);
1093 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1094 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1095 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1096 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1097 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1103 *rT = MEM(signed, EA, 2);
1105 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1106 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1107 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1108 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1109 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1115 *rT = MEM(signed, EA, 2);
1117 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1118 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1119 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1120 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1121 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1123 if (RA == 0 || RA == RT)
1124 program_interrupt(processor, cia,
1125 illegal_instruction_program_interrupt);
1127 *rT = MEM(signed, EA, 2);
1129 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1130 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1131 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1132 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1133 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1135 if (RA == 0 || RA == RT)
1136 program_interrupt(processor, cia,
1137 illegal_instruction_program_interrupt);
1139 *rT = MEM(signed, EA, 2);
1142 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1143 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1144 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1145 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1146 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1152 *rT = MEM(unsigned, EA, 4);
1154 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1155 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1156 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1157 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1158 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1164 *rT = MEM(unsigned, EA, 4);
1166 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1167 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1168 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1169 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1170 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1172 if (RA == 0 || RA == RT)
1173 program_interrupt(processor, cia,
1174 illegal_instruction_program_interrupt);
1176 *rT = MEM(unsigned, EA, 4);
1179 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1180 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1181 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1182 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1183 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1185 if (RA == 0 || RA == RT)
1186 program_interrupt(processor, cia,
1187 illegal_instruction_program_interrupt);
1189 *rT = MEM(unsigned, EA, 4);
1192 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1195 # if (RA == 0) b = 0;
1197 # EA = b + EXTS(DS_0b00);
1198 # *rT = MEM(signed, EA, 4);
1200 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1203 # if (RA == 0) b = 0;
1206 # *rT = MEM(signed, EA, 4);
1208 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1210 # if (RA == 0 || RA == RT)
1211 # program_interrupt(processor, cia
1212 # illegal_instruction_program_interrupt);
1214 # *rT = MEM(signed, EA, 4);
1217 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1220 # if (RA == 0) b = 0;
1222 # EA = b + EXTS(DS_0b00);
1223 # *rT = MEM(unsigned, EA, 8);
1225 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1228 # if (RA == 0) b = 0;
1231 # *rT = MEM(unsigned, EA, 8);
1233 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1235 # if (RA == 0 || RA == RT)
1236 # program_interrupt(processor, cia
1237 # illegal_instruction_program_interrupt);
1238 # EA = *rA + EXTS(DS_0b00);
1239 # *rT = MEM(unsigned, EA, 8);
1242 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1244 # if (RA == 0 || RA == RT)
1245 # program_interrupt(processor, cia
1246 # illegal_instruction_program_interrupt);
1248 # *rT = MEM(unsigned, EA, 8);
1254 # I.3.3.3 Fixed-Point Store Instructions
1257 0.38,6.RS,11.RA,16.D:D:::Store Byte
1258 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1259 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1260 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1261 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1269 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1270 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1271 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1272 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1273 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1281 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1282 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1283 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1284 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1285 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1288 program_interrupt(processor, cia,
1289 illegal_instruction_program_interrupt);
1294 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1295 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1296 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1297 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1298 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1301 program_interrupt(processor, cia,
1302 illegal_instruction_program_interrupt);
1307 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1308 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1309 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1310 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1311 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1319 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1320 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1321 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1322 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1323 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1331 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1332 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1333 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1334 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1335 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1338 program_interrupt(processor, cia,
1339 illegal_instruction_program_interrupt);
1344 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1345 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1346 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1347 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1348 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1351 program_interrupt(processor, cia,
1352 illegal_instruction_program_interrupt);
1357 0.36,6.RS,11.RA,16.D:D:::Store Word
1358 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1359 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1360 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1361 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1369 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
1370 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1371 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1372 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1373 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1381 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
1382 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1383 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1384 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1385 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1388 program_interrupt(processor, cia,
1389 illegal_instruction_program_interrupt);
1394 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
1395 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1396 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1397 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1398 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1401 program_interrupt(processor, cia,
1402 illegal_instruction_program_interrupt);
1407 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
1410 # if (RA == 0) b = 0;
1412 # EA = b + EXTS(DS_0b00);
1413 # STORE(EA, 8, *rS);
1414 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
1417 # if (RA == 0) b = 0;
1420 # STORE(EA, 8, *rS);
1421 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
1424 # program_interrupt(processor, cia
1425 # illegal_instruction_program_interrupt);
1426 # EA = *rA + EXTS(DS_0b00);
1427 # STORE(EA, 8, *rS);
1429 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
1432 # program_interrupt(processor, cia
1433 # illegal_instruction_program_interrupt);
1435 # STORE(EA, 8, *rS);
1440 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
1443 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
1444 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1445 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1446 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1447 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1453 *rT = SWAP_2(MEM(unsigned, EA, 2));
1455 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
1456 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1457 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1458 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1459 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1465 *rT = SWAP_4(MEM(unsigned, EA, 4));
1467 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
1468 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1469 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1470 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1471 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1477 STORE(EA, 2, SWAP_2(*rS));
1479 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
1480 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1481 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1482 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1483 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1489 STORE(EA, 4, SWAP_4(*rS));
1493 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
1496 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
1498 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
1502 # I.3.3.6 Fixed-Point Move Assist Instructions
1505 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
1507 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
1509 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
1511 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
1515 # I.3.3.7 Storage Synchronization Instructions
1517 # HACK: Rather than monitor addresses looking for a reason
1518 # to cancel a reservation. This code instead keeps
1519 # a copy of the data read from memory. Before performing
1520 # a store, the memory area is checked to see if it has
1522 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
1523 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
1524 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1525 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1526 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1533 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1534 RESERVE_DATA = MEM(unsigned, EA, 4);
1537 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
1544 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1545 RESERVE_DATA = MEM(unsigned, EA, 8);
1548 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
1549 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1550 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, ppc_insn_generic
1551 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, ppc_insn_generic
1552 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, ppc_insn_generic
1559 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1560 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
1562 CR_SET_XER_SO(0, cr_i_zero);
1565 /* ment to randomly to store, we never do! */
1566 CR_SET_XER_SO(0, 0);
1571 CR_SET_XER_SO(0, 0);
1573 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
1580 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1581 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
1583 CR_SET_XER_SO(0, cr_i_zero);
1586 /* ment to randomly to store, we never do */
1587 CR_SET_XER_SO(0, 0);
1592 CR_SET_XER_SO(0, 0);
1595 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
1596 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1597 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1598 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1599 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
1604 # I.3.3.9 Fixed-Point Arithmetic Instructions
1607 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
1608 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1609 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1610 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1611 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1612 if (RA_is_0) *rT = EXTS(SI);
1613 else *rT = *rA + EXTS(SI);
1615 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
1616 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1617 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1618 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1619 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1620 if (RA_is_0) *rT = EXTS(SI) << 16;
1621 else *rT = *rA + (EXTS(SI) << 16);
1623 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
1624 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1625 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1626 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1627 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1630 ALU_END(*rT, 0/*CA*/, OE, Rc);
1632 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
1633 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1634 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1635 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1636 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1641 ALU_END(*rT, 0/*CA*/, OE, Rc);
1643 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
1644 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1645 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1646 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1647 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1650 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1652 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
1653 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1654 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1655 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1656 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1659 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
1661 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
1662 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1663 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1664 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1665 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1670 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1672 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
1673 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1674 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1675 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1676 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1679 ALU_END(*rT, 1/*CA*/, OE, Rc);
1681 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
1682 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1683 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1684 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1685 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1686 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
1691 ALU_END(*rT, 1/*CA*/, OE, Rc);
1693 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
1694 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1695 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1696 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1697 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1701 ALU_END(*rT, 1/*CA*/, OE, Rc);
1703 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
1704 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1705 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1706 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1707 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1712 ALU_END(*rT, 1/*CA*/, OE, Rc);
1714 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
1715 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1716 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1717 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1718 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1722 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1724 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
1725 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1726 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1727 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1728 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1733 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1735 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
1736 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1737 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1738 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1739 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1742 ALU_END(*rT, 1/*CA*/, OE, Rc);
1744 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
1745 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1746 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1747 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1748 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1752 ALU_END(*rT, 1/*CA*/, OE, Rc);
1754 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
1755 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1756 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1757 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1758 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1762 ALU_END(*rT,0/*CA*/,OE,Rc);
1764 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
1765 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1766 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
1767 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
1768 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
1769 signed_word prod = *rA * EXTS(SI);
1772 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
1774 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
1775 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1776 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1777 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1778 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, ppc_insn_generic
1779 signed64 a = (signed32)(*rA);
1780 signed64 b = (signed32)(*rB);
1781 signed64 prod = a * b;
1782 signed_word t = prod;
1784 if (t != prod && OE)
1785 XER |= (xer_overflow | xer_summary_overflow);
1786 CR0_COMPARE(t, 0, Rc);
1788 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
1790 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
1791 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1792 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1793 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1794 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, ppc_insn_generic
1795 signed64 a = (signed32)(*rA);
1796 signed64 b = (signed32)(*rB);
1797 signed64 prod = a * b;
1798 signed_word t = EXTRACTED64(prod, 0, 31);
1800 CR0_COMPARE(t, 0, Rc);
1802 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
1804 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
1805 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, ppc_insn_generic
1806 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, ppc_insn_generic
1807 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, ppc_insn_generic
1808 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, ppc_insn_generic
1809 unsigned64 a = (unsigned32)(*rA);
1810 unsigned64 b = (unsigned32)(*rB);
1811 unsigned64 prod = a * b;
1812 signed_word t = EXTRACTED64(prod, 0, 31);
1814 CR0_COMPARE(t, 0, Rc);
1816 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
1818 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
1819 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, ppc_insn_generic
1820 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, ppc_insn_generic
1821 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, ppc_insn_generic
1822 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, ppc_insn_generic
1823 signed64 dividend = (signed32)(*rA);
1824 signed64 divisor = (signed32)(*rB);
1825 if (divisor == 0 /* nb 0x8000..0 is sign extended */
1826 || (dividend == 0x80000000 && divisor == -1)) {
1828 XER |= (xer_overflow | xer_summary_overflow);
1829 CR0_COMPARE(0, 0, Rc);
1832 signed64 quotent = dividend / divisor;
1834 CR0_COMPARE((signed_word)quotent, 0, Rc);
1836 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
1838 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
1839 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, ppc_insn_generic
1840 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, ppc_insn_generic
1841 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, ppc_insn_generic
1842 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, ppc_insn_generic
1843 unsigned64 dividend = (unsigned32)(*rA);
1844 unsigned64 divisor = (unsigned32)(*rB);
1847 XER |= (xer_overflow | xer_summary_overflow);
1848 CR0_COMPARE(0, 0, Rc);
1851 unsigned64 quotent = dividend / divisor;
1853 CR0_COMPARE((signed_word)quotent, 0, Rc);
1858 # I.3.3.10 Fixed-Point Compare Instructions
1861 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
1862 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1863 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1864 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1865 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1866 if (!is_64bit_mode && L)
1867 program_interrupt(processor, cia,
1868 illegal_instruction_program_interrupt);
1871 signed_word b = EXTS(SI);
1876 CR_COMPARE(BF, a, b);
1879 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
1880 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1881 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1882 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1883 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1884 if (!is_64bit_mode && L)
1885 program_interrupt(processor, cia,
1886 illegal_instruction_program_interrupt);
1898 CR_COMPARE(BF, a, b);
1901 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
1902 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1903 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1904 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1905 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1906 if (!is_64bit_mode && L)
1907 program_interrupt(processor, cia,
1908 illegal_instruction_program_interrupt);
1911 unsigned_word b = UI;
1913 a = MASKED(*rA, 32, 63);
1916 CR_COMPARE(BF, a, b);
1919 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
1920 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1921 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1922 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1923 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1924 if (!is_64bit_mode && L)
1925 program_interrupt(processor, cia,
1926 illegal_instruction_program_interrupt);
1931 a = MASKED(*rA, 32, 63);
1932 b = MASKED(*rB, 32, 63);
1938 CR_COMPARE(BF, a, b);
1943 # I.3.3.11 Fixed-Point Trap Instructions
1946 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
1948 program_interrupt(processor, cia,
1949 illegal_instruction_program_interrupt);
1951 signed_word a = *rA;
1952 signed_word b = EXTS(SI);
1953 if ((a < b && TO{0})
1955 || (a == b && TO{2})
1956 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1957 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1959 program_interrupt(processor, cia,
1960 trap_program_interrupt);
1963 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
1964 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1965 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
1966 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
1967 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1968 signed_word a = EXTENDED(*rA);
1969 signed_word b = EXTS(SI);
1970 if ((a < b && TO{0})
1972 || (a == b && TO{2})
1973 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1974 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1976 program_interrupt(processor, cia,
1977 trap_program_interrupt);
1979 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
1981 program_interrupt(processor, cia,
1982 illegal_instruction_program_interrupt);
1984 signed_word a = *rA;
1985 signed_word b = *rB;
1986 if ((a < b && TO{0})
1988 || (a == b && TO{2})
1989 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1990 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1992 program_interrupt(processor, cia,
1993 trap_program_interrupt);
1996 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
1997 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1998 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
1999 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
2000 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2001 signed_word a = EXTENDED(*rA);
2002 signed_word b = EXTENDED(*rB);
2003 if (TO == 12 && rA == rB) {
2004 ITRACE(trace_breakpoint, ("breakpoint\n"));
2005 cpu_halt(processor, cia, was_trap, 0);
2007 else if ((a < b && TO{0})
2009 || (a == b && TO{2})
2010 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2011 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2013 program_interrupt(processor, cia,
2014 trap_program_interrupt);
2017 # I.3.3.12 Fixed-Point Logical Instructions
2020 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2021 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2022 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2023 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2024 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2026 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2028 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2029 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2030 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2031 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2032 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2033 *rA = *rS & (UI << 16);
2034 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2036 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2037 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2038 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2039 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2040 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2043 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2044 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2045 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2046 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2047 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2048 *rA = *rS | (UI << 16);
2050 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2051 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2052 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2053 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2054 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2057 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2058 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2059 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2060 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2061 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2062 *rA = *rS ^ (UI << 16);
2064 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
2065 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2066 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2067 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2068 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2070 CR0_COMPARE(*rA, 0, Rc);
2072 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
2073 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2074 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2075 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2076 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2078 CR0_COMPARE(*rA, 0, Rc);
2080 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
2081 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2082 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2083 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2084 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2086 CR0_COMPARE(*rA, 0, Rc);
2088 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
2089 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2090 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2091 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2092 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2094 CR0_COMPARE(*rA, 0, Rc);
2096 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
2097 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2098 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2099 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2100 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2102 CR0_COMPARE(*rA, 0, Rc);
2104 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
2105 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2106 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2107 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2108 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2109 # *rA = ~(*rS ^ *rB); /* A === B */
2110 # CR0_COMPARE(*rA, 0, Rc);
2112 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
2113 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2114 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2115 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2116 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2118 CR0_COMPARE(*rA, 0, Rc);
2119 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
2120 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2121 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2122 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2123 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2125 CR0_COMPARE(*rA, 0, Rc);
2127 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
2128 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2129 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2130 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2131 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2132 *rA = (signed_word)(signed8)*rS;
2133 CR0_COMPARE(*rA, 0, Rc);
2135 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
2136 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2137 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2138 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2139 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2140 *rA = (signed_word)(signed16)*rS;
2141 CR0_COMPARE(*rA, 0, Rc);
2143 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2144 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2145 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2146 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2147 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2148 # *rA = (signed_word)(signed32)*rS;
2149 # CR0_COMPARE(*rA, 0, Rc);
2151 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2153 # unsigned64 mask = BIT64(0);
2154 # unsigned64 source = *rS;
2155 # while (!(source & mask) && mask != 0) {
2160 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2162 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
2163 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2164 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2165 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2166 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2168 unsigned32 mask = BIT32(0);
2169 unsigned32 source = *rS;
2170 while (!(source & mask) && mask != 0) {
2175 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2179 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2182 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
2183 # long n = (sh_5 << 4) | sh_0_4;
2184 # unsigned_word r = ROTL64(*rS, n);
2185 # long b = (mb_5 << 4) | mb_0_4;
2186 # unsigned_word m = MASK(b, 63);
2187 # signed_word result = r & m;
2189 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2191 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
2192 # long n = (sh_5 << 4) | sh_0_4;
2193 # unsigned_word r = ROTL64(*rS, n);
2194 # long e = (me_5 << 4) | me_0_4;
2195 # unsigned_word m = MASK(0, e);
2196 # signed_word result = r & m;
2198 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2200 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
2201 # long n = (sh_5 << 4) | sh_0_4;
2202 # unsigned_word r = ROTL64(*rS, n);
2203 # long b = (mb_5 << 4) | mb_0_4;
2204 # unsigned_word m = MASK(0, (64-n));
2205 # signed_word result = r & m;
2207 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2209 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2210 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2211 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2212 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2213 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2216 unsigned32 r = ROTL32(s, n);
2217 unsigned32 m = MASK(MB+32, ME+32);
2218 signed_word result = r & m;
2220 CR0_COMPARE(result, 0, Rc);
2222 ("n=%d, s=0x%x, r=0x%x, m=0x%x, result=0x%x, cr=0x%x\n",
2223 n, s, r, m, result, CR));
2225 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2226 # long n = MASKED(*rB, 58, 63);
2227 # unsigned_word r = ROTL64(*rS, n);
2228 # long b = (mb_5 << 4) | mb_0_4;
2229 # unsigned_word m = MASK(b, 63);
2230 # signed_word result = r & m;
2232 # CR0_COMPARE(result, 0, Rc);
2234 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2235 # long n = MASKED(*rB, 58, 63);
2236 # unsigned_word r = ROTL64(*rS, n);
2237 # long e = (me_5 << 4) | me_0_4;
2238 # unsigned_word m = MASK(0, e);
2239 # signed_word result = r & m;
2241 # CR0_COMPARE(result, 0, Rc);
2243 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2244 # long n = MASKED(*rB, 59, 63);
2245 # unsigned32 r = ROTL32(*rS, n);
2246 # unsigned32 m = MASK(MB+32, ME+32);
2247 # signed_word result = r & m;
2249 # CR0_COMPARE(result, 0, Rc);
2251 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
2252 # long n = (sh_5 << 4) | sh_0_4;
2253 # unsigned_word r = ROTL64(*rS, n);
2254 # long b = (mb_5 << 4) | mb_0_4;
2255 # unsigned_word m = MASK(b, (64-n));
2256 # signed_word result = (r & m) | (*rA & ~m)
2258 # CR0_COMPARE(result, 0, Rc);
2260 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2261 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2262 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2263 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2264 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2266 unsigned32 r = ROTL32(*rS, n);
2267 unsigned32 m = MASK(MB+32, ME+32);
2268 signed_word result = (r & m) | (*rA & ~m);
2270 ITRACE(trace_alu, (": n=%d *rS=0x%x r=0x%x m=0x%x result=0x%x\n",
2271 n, *rS, r, m, result));
2272 CR0_COMPARE(result, 0, Rc);
2275 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2277 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2278 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2279 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2280 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2281 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2282 int n = MASKED(*rB, 59, 63);
2283 unsigned32 source = *rS;
2284 signed_word shifted;
2286 shifted = (source << n);
2290 CR0_COMPARE(shifted, 0, Rc);
2292 ("n=%d, source=0x%x, shifted=0x%x\n",
2293 n, source, shifted));
2295 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
2297 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
2298 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2299 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2300 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2301 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2302 int n = MASKED(*rB, 59, 63);
2303 unsigned32 source = *rS;
2304 signed_word shifted;
2306 shifted = (source >> n);
2310 CR0_COMPARE(shifted, 0, Rc);
2312 ("n=%d, source=0x%x, shifted=0x%x\n",
2313 n, source, shifted));
2315 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
2317 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
2318 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2319 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2320 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2321 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2323 signed_word r = ROTL32(*rS, /*64*/32-n);
2324 signed_word m = MASK(n+32, 63);
2325 int S = MASKED(*rS, 32, 32);
2326 signed_word shifted = (r & m) | (S ? ~m : 0);
2328 if (S && ((r & ~m) & MASK(32, 63)) != 0)
2332 CR0_COMPARE(shifted, 0, Rc);
2334 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
2336 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
2337 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2338 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2339 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2340 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2341 int n = MASKED(*rB, 58, 63);
2342 int shift = (n >= 31 ? 31 : n);
2343 signed32 source = (signed32)*rS; /* signed to keep sign bit */
2344 signed32 shifted = source >> shift;
2345 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
2346 *rA = (signed_word)shifted; /* if 64bit will sign extend */
2347 if (source < 0 && (source & mask))
2351 CR0_COMPARE(shifted, 0, Rc);
2355 # I.3.3.14 Move to/from System Register Instructions
2358 0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
2359 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2360 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
2361 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
2362 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
2363 int n = (spr{5:9} << 5) | spr{0:4};
2364 if (spr{0} && IS_PROBLEM_STATE(processor))
2365 program_interrupt(processor, cia,
2366 privileged_instruction_program_interrupt);
2367 else if (!spr_is_valid(n)
2368 || spr_is_readonly(n))
2369 program_interrupt(processor, cia,
2370 illegal_instruction_program_interrupt);
2372 spreg new_val = (spr_length(n) == 64
2374 : MASKED(*rS, 32, 63));
2375 /* HACK - time base registers need to be updated immediatly */
2376 if (WITH_TIME_BASE) {
2380 cpu_set_time_base(processor,
2381 (MASKED64(cpu_get_time_base(processor), 32, 63)
2382 | INSERTED64(new_val, 0, 31)));
2385 cpu_set_time_base(processor,
2386 (MASKED64(cpu_get_time_base(processor), 0, 31)
2387 | INSERTED64(new_val, 32, 63)));
2390 cpu_set_decrementer(processor, new_val);
2402 0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
2403 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2404 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2405 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2406 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
2407 int n = (spr{5:9} << 5) | spr{0:4};
2408 if (spr{0} && IS_PROBLEM_STATE(processor))
2409 program_interrupt(processor, cia,
2410 privileged_instruction_program_interrupt);
2411 else if (!spr_is_valid(n))
2412 program_interrupt(processor, cia,
2413 illegal_instruction_program_interrupt);
2415 /* HACK - some SPR's need to get their value extracted specially */
2419 # FIXME: 604 uses SCIU{1,2} if only one bit is being set
2420 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
2421 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
2422 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2423 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2424 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
2429 unsigned_word mask = 0;
2431 for (f = 0; f < 8; f++) {
2432 if (FXM & (0x80 >> f))
2433 mask |= (0xf << 4*(7-f));
2435 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
2438 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
2440 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
2441 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2442 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2443 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2444 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
2445 *rT = (unsigned32)CR;
2448 # I.4.6.2 Floating-Point Load Instructions
2451 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
2452 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2453 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2454 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2455 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2461 *frT = DOUBLE(MEM(unsigned, EA, 4));
2463 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
2464 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2465 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2466 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2467 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2473 *frT = DOUBLE(MEM(unsigned, EA, 4));
2475 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
2476 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2477 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2478 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2479 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2482 program_interrupt(processor, cia,
2483 illegal_instruction_program_interrupt);
2485 *frT = DOUBLE(MEM(unsigned, EA, 4));
2488 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
2489 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2490 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2491 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2492 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2495 program_interrupt(processor, cia,
2496 illegal_instruction_program_interrupt);
2498 *frT = DOUBLE(MEM(unsigned, EA, 4));
2501 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
2502 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2503 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2504 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2505 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2511 *frT = MEM(unsigned, EA, 8);
2513 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
2514 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2515 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2516 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2517 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2523 *frT = MEM(unsigned, EA, 8);
2525 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
2526 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2527 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2528 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2529 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2532 program_interrupt(processor, cia,
2533 illegal_instruction_program_interrupt);
2535 *frT = MEM(unsigned, EA, 8);
2538 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
2539 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2540 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2541 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2542 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2545 program_interrupt(processor, cia,
2546 illegal_instruction_program_interrupt);
2548 *frT = MEM(unsigned, EA, 8);
2553 # I.4.6.3 Floating-Point Store Instructions
2556 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
2557 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2558 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2559 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2560 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2566 STORE(EA, 4, SINGLE(*frS));
2568 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
2569 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2570 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2571 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2572 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2578 STORE(EA, 4, SINGLE(*frS));
2580 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
2581 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2582 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2583 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2584 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2587 program_interrupt(processor, cia,
2588 illegal_instruction_program_interrupt);
2590 STORE(EA, 4, SINGLE(*frS));
2593 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
2594 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2595 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2596 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2597 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2600 program_interrupt(processor, cia,
2601 illegal_instruction_program_interrupt);
2603 STORE(EA, 4, SINGLE(*frS));
2606 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
2607 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2608 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2609 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2610 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2618 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
2619 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2620 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2621 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2622 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2630 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
2631 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2632 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2633 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2634 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2637 program_interrupt(processor, cia,
2638 illegal_instruction_program_interrupt);
2643 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
2644 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2645 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2646 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2647 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2650 program_interrupt(processor, cia,
2651 illegal_instruction_program_interrupt);
2658 # I.4.6.4 Floating-Point Move Instructions
2661 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
2662 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2663 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2664 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2665 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2669 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
2670 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2671 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2672 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2673 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2674 *frT = *frB ^ BIT64(0);
2677 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
2678 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2679 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2680 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2681 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2682 *frT = *frB & ~BIT64(0);
2685 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
2686 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2687 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2688 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2689 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2690 *frT = *frB | BIT64(0);
2696 # I.4.6.5 Floating-Point Arithmetic Instructions
2699 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
2700 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2701 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2702 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2703 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2705 if (is_invalid_operation(processor, cia,
2707 fpscr_vxsnan | fpscr_vxisi,
2710 invalid_arithemetic_operation(processor, cia,
2712 0, /*instruction_is_frsp*/
2713 0, /*instruction_is_convert_to_64bit*/
2714 0, /*instruction_is_convert_to_32bit*/
2715 0); /*single-precision*/
2719 double s = *(double*)frA + *(double*)frB;
2724 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
2725 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2726 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2727 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2728 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2730 if (is_invalid_operation(processor, cia,
2732 fpscr_vxsnan | fpscr_vxisi,
2735 invalid_arithemetic_operation(processor, cia,
2737 0, /*instruction_is_frsp*/
2738 0, /*instruction_is_convert_to_64bit*/
2739 0, /*instruction_is_convert_to_32bit*/
2740 1); /*single-precision*/
2744 float s = *(double*)frA + *(double*)frB;
2749 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
2750 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2751 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2752 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2753 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2755 if (is_invalid_operation(processor, cia,
2757 fpscr_vxsnan | fpscr_vxisi,
2760 invalid_arithemetic_operation(processor, cia,
2762 0, /*instruction_is_frsp*/
2763 0, /*instruction_is_convert_to_64bit*/
2764 0, /*instruction_is_convert_to_32bit*/
2765 0); /*single-precision*/
2769 double s = *(double*)frA - *(double*)frB;
2774 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
2775 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2776 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2777 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2778 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2780 if (is_invalid_operation(processor, cia,
2782 fpscr_vxsnan | fpscr_vxisi,
2785 invalid_arithemetic_operation(processor, cia,
2787 0, /*instruction_is_frsp*/
2788 0, /*instruction_is_convert_to_64bit*/
2789 0, /*instruction_is_convert_to_32bit*/
2790 1); /*single-precision*/
2794 float s = *(double*)frA - *(double*)frB;
2799 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
2800 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2801 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2802 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2803 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2805 if (is_invalid_operation(processor, cia,
2807 fpscr_vxsnan | fpscr_vximz,
2810 invalid_arithemetic_operation(processor, cia,
2812 0, /*instruction_is_frsp*/
2813 0, /*instruction_is_convert_to_64bit*/
2814 0, /*instruction_is_convert_to_32bit*/
2815 0); /*single-precision*/
2819 double s = *(double*)frA * *(double*)frC;
2824 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
2825 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2826 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2827 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2828 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2830 if (is_invalid_operation(processor, cia,
2832 fpscr_vxsnan | fpscr_vximz,
2835 invalid_arithemetic_operation(processor, cia,
2837 0, /*instruction_is_frsp*/
2838 0, /*instruction_is_convert_to_64bit*/
2839 0, /*instruction_is_convert_to_32bit*/
2840 1); /*single-precision*/
2844 float s = *(double*)frA * *(double*)frC;
2849 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
2850 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, ppc_insn_generic
2851 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, ppc_insn_generic
2852 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, ppc_insn_generic
2853 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, ppc_insn_generic
2855 if (is_invalid_operation(processor, cia,
2857 fpscr_vxsnan | fpscr_vxzdz,
2860 invalid_arithemetic_operation(processor, cia,
2862 0, /*instruction_is_frsp*/
2863 0, /*instruction_is_convert_to_64bit*/
2864 0, /*instruction_is_convert_to_32bit*/
2865 0); /*single-precision*/
2869 double s = *(double*)frA / *(double*)frB;
2874 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
2875 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, ppc_insn_generic
2876 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, ppc_insn_generic
2877 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, ppc_insn_generic
2878 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, ppc_insn_generic
2880 if (is_invalid_operation(processor, cia,
2882 fpscr_vxsnan | fpscr_vxzdz,
2885 invalid_arithemetic_operation(processor, cia,
2887 0, /*instruction_is_frsp*/
2888 0, /*instruction_is_convert_to_64bit*/
2889 0, /*instruction_is_convert_to_32bit*/
2890 1); /*single-precision*/
2894 float s = *(double*)frA / *(double*)frB;
2899 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
2900 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2901 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2902 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2903 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2905 double product; /*HACK! - incorrectly loosing precision ... */
2906 /* compute the multiply */
2907 if (is_invalid_operation(processor, cia,
2909 fpscr_vxsnan | fpscr_vximz,
2912 invalid_arithemetic_operation(processor, cia,
2913 (unsigned64*)&product, *frA, 0, *frC,
2914 0, /*instruction_is_frsp*/
2915 0, /*instruction_is_convert_to_64bit*/
2916 0, /*instruction_is_convert_to_32bit*/
2917 0); /*single-precision*/
2921 product = *(double*)frA * *(double*)frC;
2923 /* compute the add */
2924 if (is_invalid_operation(processor, cia,
2926 fpscr_vxsnan | fpscr_vxisi,
2929 invalid_arithemetic_operation(processor, cia,
2930 frT, product, *frB, 0,
2931 0, /*instruction_is_frsp*/
2932 0, /*instruction_is_convert_to_64bit*/
2933 0, /*instruction_is_convert_to_32bit*/
2934 0); /*single-precision*/
2938 double s = product + *(double*)frB;
2943 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
2944 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2945 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2946 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2947 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2949 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
2950 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2951 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2952 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2953 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2955 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
2956 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2957 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2958 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2959 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2961 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
2962 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2963 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2964 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2965 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2967 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
2968 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2969 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2970 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2971 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2973 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
2974 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2975 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2976 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2977 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2979 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
2980 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2981 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2982 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2983 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2987 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
2990 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
2991 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2992 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2993 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2994 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2997 unsigned64 frac_grx;
2998 /* split off cases for what to do */
2999 if (EXTRACTED64(*frB, 1, 11) < 897
3000 && EXTRACTED64(*frB, 1, 63) > 0) {
3001 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
3002 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
3004 if (EXTRACTED64(*frB, 1, 11) > 1150
3005 && EXTRACTED64(*frB, 1, 11) < 2047) {
3006 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3007 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
3009 if (EXTRACTED64(*frB, 1, 11) > 896
3010 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
3011 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
3012 if (EXTRACTED64(*frB, 1, 11) == 2047) {
3013 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
3014 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
3015 if (EXTRACTED64(*frB, 12, 12) == 0
3016 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
3019 Disabled_Exponent_Underflow:
3020 sign = EXTRACTED64(*frB, 0, 0);
3021 if (EXTRACTED64(*frB, 1, 11) == 0) {
3023 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3025 if (EXTRACTED64(*frB, 1, 11) > 0) {
3026 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3027 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3029 Denormalize_Operand:
3030 /* G|R|X == zero from above */
3031 while (exp < -126) {
3033 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
3034 | MASKED64(frac_grx, 55, 55));
3036 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
3037 Round_Single(processor, sign, &exp, &frac_grx);
3038 FPSCR_SET_XX(FPSCR & fpscr_fi);
3039 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
3040 *frT = INSERTED64(sign, 0, 0);
3041 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3042 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3044 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
3045 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
3046 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3047 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3049 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
3050 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
3051 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
3053 /*Normalize_Operand:*/
3054 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3056 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3058 *frT = (INSERTED64(sign, 0, 0)
3059 | INSERTED64(exp + 1023, 1, 11)
3060 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3063 Enabled_Exponent_Underflow:
3065 sign = EXTRACTED64(*frB, 0, 0);
3066 if (EXTRACTED64(*frB, 1, 11) == 0) {
3068 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3070 if (EXTRACTED64(*frB, 1, 11) > 0) {
3071 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3072 frac_grx = (BIT64(0) |
3073 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
3075 /*Normalize_Operand:*/
3076 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3078 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3080 Round_Single(processor, sign, &exp, &frac_grx);
3081 FPSCR_SET_XX(FPSCR & fpscr_fi);
3083 *frT = (INSERTED64(sign, 0, 0)
3084 | INSERTED64(exp + 1023, 1, 11)
3085 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3086 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3087 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3089 Disabled_Exponent_Overflow:
3091 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
3092 if (EXTRACTED64(*frB, 0, 0) == 0) {
3093 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
3094 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3096 if (EXTRACTED64(*frB, 0, 0) == 1) {
3097 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
3098 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3101 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
3102 if (EXTRACTED64(*frB, 0, 0) == 0) {
3103 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
3104 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3106 if (EXTRACTED64(*frB, 0, 0) == 1) {
3107 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
3108 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3111 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
3112 if (EXTRACTED64(*frB, 0, 0) == 0) {
3113 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
3114 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3116 if (EXTRACTED64(*frB, 0, 0) == 1) {
3117 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
3118 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3121 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
3122 if (EXTRACTED64(*frB, 0, 0) == 0) {
3123 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
3124 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3126 if (EXTRACTED64(*frB, 0, 0) == 1) {
3127 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
3128 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3131 /* FPSCR[FR] <- undefined */
3135 Enabled_Exponent_Overflow:
3136 sign = EXTRACTED64(*frB, 0, 0);
3137 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3138 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3139 Round_Single(processor, sign, &exp, &frac_grx);
3140 FPSCR_SET_XX(FPSCR & fpscr_fi);
3144 *frT = (INSERTED64(sign, 0, 0)
3145 | INSERTED64(exp + 1023, 1, 11)
3146 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3147 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3148 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3152 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3153 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3159 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3160 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3165 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
3166 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
3171 FPSCR_OR_VX(fpscr_vxsnan);
3172 if ((FPSCR & fpscr_ve) == 0) {
3173 *frT = (MASKED64(*frB, 0, 11)
3175 | MASKED64(*frB, 13, 34));
3176 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
3182 sign = EXTRACTED64(*frB, 0, 0);
3183 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3184 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3185 Round_Single(processor, sign, &exp, &frac_grx);
3186 FPSCR_SET_XX(FPSCR & fpscr_fi);
3187 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3188 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
3189 *frT = (INSERTED64(sign, 0, 0)
3190 | INSERTED64(exp + 1023, 1, 11)
3191 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3192 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3193 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3197 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
3199 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
3201 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
3203 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
3204 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
3205 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3206 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3207 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3209 convert_to_integer(processor, cia,
3211 fpscr_rn_round_towards_zero, 32);
3214 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
3215 int sign = EXTRACTED64(*frB, 0, 0);
3217 unsigned64 frac = *frB;
3218 if (frac == 0) goto Zero_Operand;
3219 if (sign == 1) frac = ~frac + 1;
3220 while (EXTRACTED64(frac, 0, 0) == 0) {
3221 /*??? do the loop 0 times if (FRB) = max negative integer */
3222 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
3225 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
3226 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3227 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3228 *frT = (INSERTED64(sign, 0, 0)
3229 | INSERTED64(exp + 1023, 1, 11)
3230 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
3236 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3243 # I.4.6.7 Floating-Point Compare Instructions
3246 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
3247 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
3248 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3249 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3250 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3253 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3254 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3255 else if (is_less_than(frA, frB))
3256 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3257 else if (is_greater_than(frA, frB))
3258 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3260 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3262 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3263 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
3264 FPSCR_OR_VX(fpscr_vxsnan);
3267 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
3268 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
3269 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3270 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3271 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3274 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3275 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3276 else if (is_less_than(frA, frB))
3277 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3278 else if (is_greater_than(frA, frB))
3279 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3281 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3283 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3284 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
3285 FPSCR_OR_VX(fpscr_vxsnan);
3286 if ((FPSCR & fpscr_ve) == 0)
3287 FPSCR_OR_VX(fpscr_vxvc);
3289 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
3290 FPSCR_OR_VX(fpscr_vxvc);
3296 # I.4.6.8 Floating-Point Status and Control Register Instructions
3299 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
3301 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
3303 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
3305 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
3307 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
3309 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
3313 # I.A.1.1 Floating-Point Store Instruction
3315 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
3318 # I.A.1.2 Floating-Point Arithmetic Instructions
3321 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
3323 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
3325 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
3327 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
3330 # I.A.1.3 Floating-Point Select Instruction
3333 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
3337 # II.3.2 Cache Management Instructions
3340 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
3341 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3342 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3343 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3344 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3345 /* blindly flush all instruction cache entries */
3346 #if WITH_IDECODE_CACHE_SIZE
3347 cpu_flush_icache(processor);
3350 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
3351 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3352 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3353 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3354 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3355 cpu_synchronize_context(processor);
3359 # II.3.2.2 Data Cache Instructions
3362 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
3363 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3364 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3365 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3366 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3367 TRACE(trace_tbd,("Data Cache Block Touch\n"));
3369 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
3370 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3371 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3372 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3373 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3374 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
3376 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
3377 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3378 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, ppc_insn_generic
3379 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, ppc_insn_generic
3380 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3381 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
3383 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
3384 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3385 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, ppc_insn_generic
3386 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, ppc_insn_generic
3387 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3388 TRACE(trace_tbd,("Data Cache Block Store\n"));
3390 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
3391 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3392 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, ppc_insn_generic
3393 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, ppc_insn_generic
3394 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3395 TRACE(trace_tbd,("Data Cache Block Flush\n"));
3398 # II.3.3 Enforce In-order Execution of I/O Instruction
3401 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
3402 /* Since this model has no instruction overlap
3403 this instruction need do nothing */
3406 # II.4.1 Time Base Instructions
3409 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
3410 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
3411 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
3412 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
3413 int n = (tbr{5:9} << 5) | tbr{0:4};
3415 if (is_64bit_implementation) *rT = TB;
3416 else *rT = EXTRACTED64(TB, 32, 63);
3418 else if (n == 269) {
3419 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
3420 else *rT = EXTRACTED64(TB, 0, 31);
3423 program_interrupt(processor, cia,
3424 illegal_instruction_program_interrupt);
3428 # III.2.3.1 System Linkage Instructions
3431 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
3432 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3433 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3434 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3435 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
3436 if (IS_PROBLEM_STATE(processor)) {
3437 program_interrupt(processor, cia,
3438 privileged_instruction_program_interrupt);
3441 MSR = (MASKED(SRR1, 0, 32)
3442 | MASKED(SRR1, 37, 41)
3443 | MASKED(SRR1, 48, 63));
3444 NIA = MASKED(SRR0, 0, 61);
3445 cpu_synchronize_context(processor);
3449 # III.3.4.1 Move to/from System Register Instructions
3452 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
3453 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
3454 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
3455 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3456 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3457 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3458 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3459 if (IS_PROBLEM_STATE(processor))
3460 program_interrupt(processor, cia,
3461 privileged_instruction_program_interrupt);
3465 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
3466 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3467 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
3468 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
3469 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
3470 if (IS_PROBLEM_STATE(processor))
3471 program_interrupt(processor, cia,
3472 privileged_instruction_program_interrupt);
3478 # III.4.11.1 Cache Management Instructions
3481 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
3482 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3483 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3484 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3485 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3486 if (IS_PROBLEM_STATE(processor))
3487 program_interrupt(processor, cia,
3488 privileged_instruction_program_interrupt);
3490 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
3493 # III.4.11.2 Segment Register Manipulation Instructions
3496 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
3497 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3498 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3499 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3500 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3501 if (IS_PROBLEM_STATE(processor))
3502 program_interrupt(processor, cia,
3503 privileged_instruction_program_interrupt);
3507 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
3508 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3509 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3510 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3511 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3512 if (IS_PROBLEM_STATE(processor))
3513 program_interrupt(processor, cia,
3514 privileged_instruction_program_interrupt);
3516 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
3518 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
3519 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
3520 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3521 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3522 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3523 if (IS_PROBLEM_STATE(processor))
3524 program_interrupt(processor, cia,
3525 privileged_instruction_program_interrupt);
3529 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
3530 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
3531 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3532 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3533 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3534 if (IS_PROBLEM_STATE(processor))
3535 program_interrupt(processor, cia,
3536 privileged_instruction_program_interrupt);
3538 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
3542 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
3545 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
3547 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
3549 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
3551 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
3553 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
3557 # III.A.1.2 External Access Instructions
3560 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
3562 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed