2 # This file is part of the program psim.
4 # Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
8 # The pseudo-code that appears below, translated into C, was copied
9 # by Andrew Cagney of Moss Vale, Australia.
11 # This pseudo-code is copied by permission from the publication
12 # "The PowerPC Architecture: A Specification for A New Family of
13 # RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by
14 # International Business Machines Corporation.
16 # THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER
17 # EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES
18 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 # This program is free software; you can redistribute it and/or modify
23 # it under the terms of the GNU General Public License as published by
24 # the Free Software Foundation; either version 2 of the License, or
25 # (at your option) any later version.
27 # This program is distributed in the hope that it will be useful,
28 # but WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 # GNU General Public License for more details.
32 # You should have received a copy of the GNU General Public License
33 # along with this program; if not, write to the Free Software
34 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 # 1 Instruction format as a `start-bit,content' pairs.
42 # the content is one of a digit, field name or `/' (aka.0)
46 # 3 Flags: 64 - 64bit only
47 # f - floating point enabled required
54 # For flags marked 'model', the fields are interpreted as follows:
62 # 4 String name for model
64 # 5 Specific CPU model, must be an identifier
66 # 6 Comma separated list of functional units
69 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
70 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
71 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
72 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
76 typedef enum _ppc_function_unit {
77 PPC_UNIT_BAD, /* unknown function unit */
78 PPC_UNIT_IU, /* integer unit (601/603 style) */
79 PPC_UNIT_SRU, /* system register unit (601/603 style) */
80 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
81 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
82 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
83 PPC_UNIT_FPU, /* floating point unit */
84 PPC_UNIT_LSU, /* load/store unit */
85 PPC_UNIT_BPU, /* branch unit */
89 /* Structure to hold timing information on a per instruction basis */
91 ppc_function_unit first_unit; /* first functional unit this insn could use */
92 ppc_function_unit second_unit; /* second 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 unsigned32 flags; /* any flags that are needed */
98 /* Register mappings */
99 #define PPC_INT_REG 0 /* start of integer registers */
100 #define PPC_FLOAT_REG (PPC_INT_REG + 32) /* start of floating point registers */
101 #define PPC_CR_REG (PPC_FLOAT_REG + 32) /* start of CR0 .. CR7 */
102 #define PPC_SPR_REG (PPC_CR_REG + 8) /* start of special purpose registers */
103 #define PPC_FPSCR_REG (PPC_SPR_REG + 1024) /* start of fpscr register */
104 #define NR_PPC_REGS (PPC_FPSCR_REG + 1) /* # of registers to allocate */
106 /* Structure for each register to indicate whether it is free or not */
107 typedef struct _model_reg model_reg;
109 model_reg *next; /* next register to be released */
110 int in_use; /* non zero if register is used */
113 /* Structure for each functional unit that is busy */
114 typedef struct _model_busy model_busy;
116 model_busy *next; /* next function unit */
117 model_reg *reg; /* list of registers to release */
118 ppc_function_unit unit; /* function unit name */
119 signed16 issue; /* # of cycles until unit can accept another insn */
120 signed16 done; /* # of cycles until insn is done */
123 /* Structure to hold the current state information for the simulated CPU model */
125 cpu *processor; /* point back to processor */
126 const char *name; /* model name */
127 const model_time *timing; /* timing information */
128 model_busy *busy_list; /* list of busy function units */
129 model_busy *free_list; /* list of model_busy structs not in use */
130 model_reg registers[NR_PPC_REGS]; /* register status */
131 count_type nr_cycles; /* # cycles */
132 count_type nr_branches; /* # branches */
133 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
134 count_type nr_branch_predict_trues; /* # branches predicted correctly */
135 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
136 count_type nr_stalls_data; /* # of stalls for data */
137 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
138 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
139 count_type nr_insns_not_handled; /* # of instructions not handled */
140 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
141 int insn_handled; /* whether last insn was handled */
142 unsigned_1 busy[nr_ppc_function_units]; /* whether a function is busy or not */
145 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
146 "unknown functional unit instruction",
147 "integer functional unit instruction",
148 "system register functional unit instruction",
149 "1st single cycle integer functional unit instruction",
150 "2nd single cycle integer functional unit instruction",
151 "multiple cycle integer functional unit instruction",
152 "floating point functional unit instruction",
153 "load/store functional unit instruction",
154 "branch functional unit instruction",
157 # Code called after executing the semantics of the function
158 void::model-function::model_cleanup:itable_index index, model_data *model_ptr
159 if (model_ptr->insn_handled)
160 model_ptr->insn_handled = 0;
162 model_ptr->nr_insns_not_handled++;
163 TRACE(trace_tbd,("model specific code for %s not done\n", itable[index].name));
166 # Advance state to next cycle, releasing any registers allocated
167 void::model-internal::model_new_cycle:model_data *model_ptr
168 model_busy *cur_busy = model_ptr->busy_list;
169 model_busy *free_list = model_ptr->free_list;
170 model_busy *next_busy = (model_busy *)0;
173 model_ptr->nr_cycles++;
174 for ( ; cur_busy; cur_busy = next) {
175 next = cur_busy->next;
176 if (--cur_busy->done <= 0) { /* function unit done, release registers */
177 model_reg *reg = cur_busy->reg;
178 TRACE(trace_model,("done, retiring %s\n", ppc_function_unit_name[cur_busy->unit]));
180 TRACE(trace_model,("freeing up reg, address 0x%lx (%d)\n", (long)reg, reg - &model_ptr->registers[0]));
184 model_ptr->busy[cur_busy->unit] = 0;
185 cur_busy->next = free_list;
186 free_list = cur_busy;
188 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
189 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
190 model_ptr->busy[cur_busy->unit] = 0;
191 cur_busy->next = next_busy;
192 next_busy = cur_busy;
195 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
196 ppc_function_unit_name[cur_busy->unit],
199 cur_busy->next = next_busy;
200 next_busy = cur_busy;
204 model_ptr->busy_list = next_busy;
205 model_ptr->free_list = free_list;
207 # Mark a function unit as busy, return the busy structure so regs can be added to be released
208 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
211 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
212 model_ptr->insn_handled = 1;
214 if (!model_ptr->free_list) {
215 busy = ZALLOC(model_busy);
218 busy = model_ptr->free_list;
219 model_ptr->free_list = busy->next;
220 busy->reg = (model_reg *)0;
222 busy->next = model_ptr->busy_list;
226 model_ptr->busy_list = busy;
227 model_ptr->busy[unit] = 1;
228 model_ptr->nr_units[unit]++;
231 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
232 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
233 ppc_function_unit first_unit = time_ptr->first_unit;
234 ppc_function_unit second_unit = time_ptr->second_unit;
235 int stall_increment = 0;
238 if (!model_ptr->busy[first_unit])
239 return model_make_busy(model_ptr, first_unit,
240 model_ptr->timing[index].issue,
241 model_ptr->timing[index].done);
243 if (!model_ptr->busy[second_unit])
244 return model_make_busy(model_ptr, second_unit,
245 model_ptr->timing[index].issue,
246 model_ptr->timing[index].done);
248 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
249 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
251 model_new_cycle(model_ptr);
254 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
255 void::model-function::model_serialize:itable_index index, model_data *model_ptr
256 while (model_ptr->busy_list) {
257 TRACE(trace_model,("waiting for pipeline to empty\n"));
258 model_ptr->nr_stalls_serialize++;
259 model_new_cycle(model_ptr);
261 (void) model_make_busy(model_ptr,
262 model_ptr->timing[index].first_unit,
263 model_ptr->timing[index].issue,
264 model_ptr->timing[index].done);
266 # Wait for a CR to become unbusy
267 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
270 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
273 while (model_ptr->registers[cr_var + PPC_CR_REG].in_use) {
274 TRACE(trace_model,("waiting for CR %d\n", cr_var));
275 model_ptr->nr_stalls_data++;
276 model_new_cycle(model_ptr);
279 # Schedule an instruction that takes 2 integer input registers and produces an output register & possibly sets CR0
280 void::model-function::ppc_insn_int2:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA, signed_word *rB, unsigned Rc
281 if (!WITH_MODEL_ISSUE)
285 registers *cpu_regs = cpu_registers(processor);
286 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]) + PPC_INT_REG;
287 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]) + PPC_INT_REG;
288 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]) + PPC_INT_REG;
289 model_reg *ppc_regs = model_ptr->registers;
290 model_busy *busy_ptr;
292 if (ppc_regs[ppc_RA].in_use | ppc_regs[ppc_RB].in_use) {
293 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
295 while (ppc_regs[ppc_RA].in_use | ppc_regs[ppc_RB].in_use) {
296 model_ptr->nr_stalls_data++;
297 model_new_cycle(model_ptr);
301 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
302 ppc_regs[ppc_RD].next = (model_reg *)0;
303 ppc_regs[ppc_RD].in_use = 1;
305 busy_ptr->reg = &ppc_regs[ppc_RD];
307 model_reg *reg_CR0 = &ppc_regs[0 + PPC_CR_REG];
308 reg_CR0->next = &ppc_regs[ppc_RD];
309 busy_ptr->reg = reg_CR0;
313 # Schedule an instruction that takes 1 integer input registers and produces an output register & possibly sets CR0
314 void::model-function::ppc_insn_int1:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA, unsigned Rc
315 if (!WITH_MODEL_ISSUE)
319 registers *cpu_regs = cpu_registers(processor);
320 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]) + PPC_INT_REG;
321 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]) + PPC_INT_REG;
322 model_reg *ppc_regs = model_ptr->registers;
323 model_busy *busy_ptr;
325 if (ppc_regs[ppc_RA].in_use) {
326 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
328 while (ppc_regs[ppc_RA].in_use) {
329 model_ptr->nr_stalls_data++;
330 model_new_cycle(model_ptr);
334 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
335 ppc_regs[ppc_RD].next = (model_reg *)0;
336 ppc_regs[ppc_RD].in_use = 1;
338 busy_ptr->reg = &ppc_regs[ppc_RD];
340 model_reg *reg_CR0 = &ppc_regs[0 + PPC_CR_REG];
341 reg_CR0->next = &ppc_regs[ppc_RD];
342 busy_ptr->reg = reg_CR0;
346 # Schedule an instruction that takes no integer input registers and produces an output register & possibly sets CR0
347 void::model-function::ppc_insn_int0:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, unsigned Rc
348 if (!WITH_MODEL_ISSUE)
352 registers *cpu_regs = cpu_registers(processor);
353 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]) + PPC_INT_REG;
354 model_reg *ppc_regs = model_ptr->registers;
355 model_busy *busy_ptr;
357 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
358 ppc_regs[ppc_RD].next = (model_reg *)0;
359 ppc_regs[ppc_RD].in_use = 1;
361 busy_ptr->reg = &ppc_regs[ppc_RD];
363 model_reg *reg_CR0 = &ppc_regs[0 + PPC_CR_REG];
364 reg_CR0->next = &ppc_regs[ppc_RD];
365 busy_ptr->reg = reg_CR0;
369 # Schedule an instruction that takes 2 integer input registers and produces an output register & updates a second register
370 void::model-function::ppc_insn_int2_update:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA, signed_word *rB
371 if (!WITH_MODEL_ISSUE)
375 registers *cpu_regs = cpu_registers(processor);
376 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]) + PPC_INT_REG;
377 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]) + PPC_INT_REG;
378 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]) + PPC_INT_REG;
379 model_reg *ppc_regs = model_ptr->registers;
380 model_busy *busy_ptr;
382 if (ppc_regs[ppc_RA].in_use | ppc_regs[ppc_RB].in_use) {
383 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
385 while (ppc_regs[ppc_RA].in_use | ppc_regs[ppc_RB].in_use) {
386 model_ptr->nr_stalls_data++;
387 model_new_cycle(model_ptr);
391 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
392 ppc_regs[ppc_RA].next = (model_reg *)0;
393 ppc_regs[ppc_RA].in_use = 1;
395 ppc_regs[ppc_RD].next = &ppc_regs[ppc_RA];
396 ppc_regs[ppc_RD].in_use = 1;
397 busy_ptr->reg = &ppc_regs[ppc_RD];
400 # Schedule an instruction that takes 1 integer input registers and produces an output register & updates the other register
401 void::model-function::ppc_insn_int1_update:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA
402 if (!WITH_MODEL_ISSUE)
406 registers *cpu_regs = cpu_registers(processor);
407 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]) + PPC_INT_REG;
408 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]) + PPC_INT_REG;
409 model_reg *ppc_regs = model_ptr->registers;
410 model_busy *busy_ptr;
412 if (ppc_regs[ppc_RA].in_use) {
413 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
415 while (ppc_regs[ppc_RA].in_use) {
416 model_ptr->nr_stalls_data++;
417 model_new_cycle(model_ptr);
421 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
422 ppc_regs[ppc_RA].next = (model_reg *)0;
423 ppc_regs[ppc_RA].in_use = 1;
425 ppc_regs[ppc_RD].next = &ppc_regs[ppc_RA];
426 ppc_regs[ppc_RD].in_use = 1;
427 busy_ptr->reg = &ppc_regs[ppc_RD];
430 # Schedule an instruction that takes 2 integer input registers and produces no output register
431 void::model-function::ppc_insn_int2_noout:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rA, signed_word *rB
432 if (!WITH_MODEL_ISSUE)
436 registers *cpu_regs = cpu_registers(processor);
437 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]) + PPC_INT_REG;
438 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]) + PPC_INT_REG;
439 model_reg *ppc_regs = model_ptr->registers;
441 if (ppc_regs[ppc_RA].in_use | ppc_regs[ppc_RB].in_use) {
442 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
444 while (ppc_regs[ppc_RA].in_use | ppc_regs[ppc_RB].in_use) {
445 model_ptr->nr_stalls_data++;
446 model_new_cycle(model_ptr);
450 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
453 # Schedule an instruction that takes 1 integer input registers and produces no output register
454 void::model-function::ppc_insn_int1_noout:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rA
455 if (!WITH_MODEL_ISSUE)
459 registers *cpu_regs = cpu_registers(processor);
460 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]) + PPC_INT_REG;
461 model_reg *ppc_regs = model_ptr->registers;
463 if (ppc_regs[ppc_RA].in_use) {
464 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
466 while (ppc_regs[ppc_RA].in_use) {
467 model_ptr->nr_stalls_data++;
468 model_new_cycle(model_ptr);
472 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
475 # Schedule an instruction that takes no input registers and produces no output
476 void::model-function::ppc_insn_int0_noout:itable_index index, cpu *processor, model_data *model_ptr
477 if (!WITH_MODEL_ISSUE)
481 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
484 # Schedule an instruction that takes 2 integer input registers and produces a CR output register
485 void::model-function::ppc_insn_int2_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, signed_word *rA, signed_word *rB
486 if (!WITH_MODEL_ISSUE)
490 registers *cpu_regs = cpu_registers(processor);
491 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]) + PPC_INT_REG;
492 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]) + PPC_INT_REG;
493 const unsigned ppc_CRD = CRD + PPC_CR_REG;
494 model_reg *ppc_regs = model_ptr->registers;
495 model_busy *busy_ptr;
497 if (ppc_regs[ppc_RA].in_use | ppc_regs[ppc_RB].in_use) {
498 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
500 while (ppc_regs[ppc_RA].in_use | ppc_regs[ppc_RB].in_use) {
501 model_ptr->nr_stalls_data++;
502 model_new_cycle(model_ptr);
506 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
507 ppc_regs[ppc_CRD].next = (model_reg *)0;
508 ppc_regs[ppc_CRD].in_use = 1;
509 busy_ptr->reg = &ppc_regs[ppc_CRD];
512 # Schedule an instruction that takes 1 integer input register and produces a CR output register
513 void::model-function::ppc_insn_int1_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, signed_word *rA
514 if (!WITH_MODEL_ISSUE)
518 registers *cpu_regs = cpu_registers(processor);
519 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]) + PPC_INT_REG;
520 const unsigned ppc_CRD = CRD + PPC_CR_REG;
521 model_reg *ppc_regs = model_ptr->registers;
522 model_busy *busy_ptr;
524 if (ppc_regs[ppc_RA].in_use) {
525 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
527 while (ppc_regs[ppc_RA].in_use) {
528 model_ptr->nr_stalls_data++;
529 model_new_cycle(model_ptr);
533 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
534 ppc_regs[ppc_CRD].next = (model_reg *)0;
535 ppc_regs[ppc_CRD].in_use = 1;
536 busy_ptr->reg = &ppc_regs[ppc_CRD];
539 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
540 void::model-function::ppc_insn_from_spr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, unsigned nSPR
541 if (!WITH_MODEL_ISSUE)
545 registers *cpu_regs = cpu_registers(processor);
546 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]) + PPC_INT_REG;
547 const unsigned ppc_SPR = nSPR + PPC_SPR_REG;
548 model_reg *ppc_regs = model_ptr->registers;
549 model_busy *busy_ptr;
551 while (ppc_regs[ppc_SPR].in_use) {
552 model_ptr->nr_stalls_data++;
553 model_new_cycle(model_ptr);
556 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
557 ppc_regs[ppc_RD].next = (model_reg *)0;
558 ppc_regs[ppc_RD].in_use = 1;
559 busy_ptr->reg = &ppc_regs[ppc_RD];
562 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
563 void::model-function::ppc_insn_to_spr:itable_index index, cpu *processor, model_data *model_ptr, unsigned nSPR, signed_word *rS
564 if (!WITH_MODEL_ISSUE)
568 registers *cpu_regs = cpu_registers(processor);
569 const unsigned ppc_RS = (rS - &cpu_regs->gpr[0]) + PPC_INT_REG;
570 const unsigned ppc_SPR = nSPR + PPC_SPR_REG;
571 model_reg *ppc_regs = model_ptr->registers;
572 model_busy *busy_ptr;
574 while (ppc_regs[ppc_RS].in_use) {
575 model_ptr->nr_stalls_data++;
576 model_new_cycle(model_ptr);
579 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
580 ppc_regs[ppc_SPR].next = (model_reg *)0;
581 ppc_regs[ppc_SPR].in_use = 1;
582 busy_ptr->reg = &ppc_regs[ppc_SPR];
585 # Schedule a MFCR instruction that moves the CR into an integer regsiter
586 void::model-function::ppc_insn_mfcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD
587 if (!WITH_MODEL_ISSUE)
591 registers *cpu_regs = cpu_registers(processor);
592 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]) + PPC_INT_REG;
593 model_reg *ppc_regs = model_ptr->registers;
594 model_busy *busy_ptr;
596 while (ppc_regs[0 + PPC_CR_REG].in_use
597 | ppc_regs[1 + PPC_CR_REG].in_use
598 | ppc_regs[2 + PPC_CR_REG].in_use
599 | ppc_regs[3 + PPC_CR_REG].in_use
600 | ppc_regs[4 + PPC_CR_REG].in_use
601 | ppc_regs[5 + PPC_CR_REG].in_use
602 | ppc_regs[6 + PPC_CR_REG].in_use
603 | ppc_regs[7 + PPC_CR_REG].in_use) {
605 model_ptr->nr_stalls_data++;
606 model_new_cycle(model_ptr);
609 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
610 ppc_regs[ppc_RD].next = (model_reg *)0;
611 ppc_regs[ppc_RD].in_use = 1;
612 busy_ptr->reg = &ppc_regs[ppc_RD];
615 # Schedule a MTCR instruction that moves an integer register into the CR
616 void::model-function::ppc_insn_mtcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rT
617 if (!WITH_MODEL_ISSUE)
621 registers *cpu_regs = cpu_registers(processor);
622 const unsigned ppc_RT = (rT - &cpu_regs->gpr[0]) + PPC_INT_REG;
623 model_reg *ppc_regs = model_ptr->registers;
624 model_busy *busy_ptr;
628 if (ppc_regs[ppc_RT].in_use) {
629 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
631 while (ppc_regs[ppc_RT].in_use) {
632 model_ptr->nr_stalls_data++;
633 model_new_cycle(model_ptr);
637 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
638 prev_reg = (model_reg *)0;
639 for (i = 0; i < 8; i++) {
640 ppc_regs[i + PPC_CR_REG].next = prev_reg;
641 ppc_regs[i + PPC_CR_REG].in_use = 1;
642 prev_reg = &ppc_regs[i + PPC_CR_REG];
644 busy_ptr->reg = prev_reg;
647 # Convert a BIT32(x) number back into the original number
648 int::model-internal::ppc_undo_bit32:unsigned bitmask
649 unsigned u = 0x80000000;
651 while (u && (u & bitmask) == 0) {
658 # Schedule an instruction that takes 2 CR input registers and produces an output CR register
659 void::model-function::ppc_insn_cr2:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned crA_bit, unsigned crB_bit
660 if (!WITH_MODEL_ISSUE)
664 const unsigned ppc_CRA = ppc_undo_bit32(crA_bit) + PPC_CR_REG;
665 const unsigned ppc_CRB = ppc_undo_bit32(crB_bit) + PPC_CR_REG;
666 const unsigned ppc_CRD = crD + PPC_CR_REG;
667 model_reg *ppc_regs = model_ptr->registers;
668 model_busy *busy_ptr;
670 while (ppc_regs[ppc_CRA].in_use | ppc_regs[ppc_CRB].in_use) {
671 model_ptr->nr_stalls_data++;
672 model_new_cycle(model_ptr);
675 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
676 ppc_regs[ppc_CRD].next = (model_reg *)0;
677 ppc_regs[ppc_CRD].in_use = 1;
678 busy_ptr->reg = &ppc_regs[ppc_CRD];
681 # Schedule an instruction that takes 1 CR input registers and produces an output CR register
682 void::model-function::ppc_insn_cr1:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned CRA
683 if (!WITH_MODEL_ISSUE)
687 const unsigned ppc_CRA = CRA + PPC_CR_REG;
688 const unsigned ppc_CRD = crD + PPC_CR_REG;
689 model_reg *ppc_regs = model_ptr->registers;
690 model_busy *busy_ptr;
692 while (ppc_regs[ppc_CRA].in_use) {
693 model_ptr->nr_stalls_data++;
694 model_new_cycle(model_ptr);
697 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
698 ppc_regs[ppc_CRD].next = (model_reg *)0;
699 ppc_regs[ppc_CRD].in_use = 1;
700 busy_ptr->reg = &ppc_regs[ppc_CRD];
703 model_data *::model-function::model_create:cpu *processor
704 model_data *model_ptr = ZALLOC(model_data);
705 ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
706 model_ptr->name = model_name[CURRENT_MODEL];
707 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
708 model_ptr->processor = processor;
709 model_ptr->nr_cycles = 1;
712 void::model-function::model_init:model_data *model_ptr
714 void::model-function::model_halt:model_data *model_ptr
715 /* Let pipeline drain */
716 while (model_ptr->busy_list)
717 model_new_cycle(model_ptr);
719 model_print *::model-function::model_mon_info:model_data *model_ptr
724 head = tail = ZALLOC(model_print);
725 tail->count = model_ptr->nr_cycles;
726 tail->name = "cycle";
727 tail->suffix_plural = "s";
728 tail->suffix_singular = "";
730 if (model_ptr->nr_stalls_data) {
731 tail->next = ZALLOC(model_print);
733 tail->count = model_ptr->nr_stalls_data;
734 tail->name = "stall";
735 tail->suffix_plural = "s waiting for data";
736 tail->suffix_singular = " waiting for data";
739 if (model_ptr->nr_stalls_unit) {
740 tail->next = ZALLOC(model_print);
742 tail->count = model_ptr->nr_stalls_unit;
743 tail->name = "stall";
744 tail->suffix_plural = "s waiting for a function unit";
745 tail->suffix_singular = " waiting for a function unit";
748 if (model_ptr->nr_stalls_serialize) {
749 tail->next = ZALLOC(model_print);
751 tail->count = model_ptr->nr_stalls_serialize;
752 tail->name = "stall";
753 tail->suffix_plural = "s waiting for serialization";
754 tail->suffix_singular = " waiting for serialization";
757 if (model_ptr->nr_insns_not_handled) {
758 tail->next = ZALLOC(model_print);
760 tail->count = model_ptr->nr_insns_not_handled;
761 tail->name = "instruction";
762 tail->suffix_plural = "s that were not accounted for in timing info";
763 tail->suffix_singular = " that was not accounted for in timing info";
766 if (model_ptr->nr_branches) {
767 tail->next = ZALLOC(model_print);
769 tail->count = model_ptr->nr_branches;
770 tail->name = "branch";
771 tail->suffix_plural = "es";
772 tail->suffix_singular = "";
775 if (model_ptr->nr_branches_fallthrough) {
776 tail->next = ZALLOC(model_print);
778 tail->count = model_ptr->nr_branches_fallthrough;
779 tail->name = "conditional branch";
780 tail->suffix_plural = "es fell through";
781 tail->suffix_singular = " fell through";
784 if (model_ptr->nr_branch_predict_trues) {
785 tail->next = ZALLOC(model_print);
787 tail->count = model_ptr->nr_branch_predict_trues;
788 tail->name = "successful branch prediction";
789 tail->suffix_plural = "s";
790 tail->suffix_singular = "";
793 if (model_ptr->nr_branch_predict_falses) {
794 tail->next = ZALLOC(model_print);
796 tail->count = model_ptr->nr_branch_predict_falses;
797 tail->name = "unsuccessful branch prediction";
798 tail->suffix_plural = "s";
799 tail->suffix_singular = "";
802 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
803 if (model_ptr->nr_units[i]) {
804 tail->next = ZALLOC(model_print);
806 tail->count = model_ptr->nr_units[i];
807 tail->name = ppc_function_unit_name[i];
808 tail->suffix_plural = "s";
809 tail->suffix_singular = "";
813 tail->next = (model_print *)0;
816 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
818 model_print *next = ptr->next;
823 void::model-function::model_branches:model_data *model_ptr, int failed
824 model_ptr->nr_units[PPC_UNIT_BPU]++;
825 model_ptr->insn_handled = 1;
827 model_ptr->nr_branches_fallthrough++;
829 model_ptr->nr_branches++;
830 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
832 void::model-function::model_branch_predict:model_data *model_ptr, int success
834 model_ptr->nr_branch_predict_trues++;
836 model_ptr->nr_branch_predict_falses++;
838 # The following (illegal) instruction is `known' by gen and is
839 # called when ever an illegal instruction is encountered
841 program_interrupt(processor, cia,
842 illegal_instruction_program_interrupt);
846 # The following (floating point unavailable) instruction is `known' by gen
847 # and is called when ever an a floating point instruction is to be
848 # executed but floating point is make unavailable by the MSR
849 ::internal::floating_point_unavailable
850 floating_point_unavailable_interrupt(processor, cia);
855 # Floating point support functions
858 # Convert 32bit single to 64bit double
859 unsigned64::function::DOUBLE:unsigned32 WORD
861 if (EXTRACTED32(WORD, 1, 8) > 0
862 && EXTRACTED32(WORD, 1, 8) < 255) {
863 /* normalized operand */
864 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
865 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
866 | INSERTED64(not_word_1_1, 2, 2)
867 | INSERTED64(not_word_1_1, 3, 3)
868 | INSERTED64(not_word_1_1, 4, 4)
869 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
871 else if (EXTRACTED32(WORD, 1, 8) == 0
872 && EXTRACTED32(WORD, 9, 31) != 0) {
873 /* denormalized operand */
874 int sign = EXTRACTED32(WORD, 0, 0);
876 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
877 /* normalize the operand */
878 while (MASKED64(frac, 0, 0) == 0) {
882 FRT = (INSERTED64(sign, 0, 0)
883 | INSERTED64(exp + 1023, 1, 11)
884 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
886 else if (EXTRACTED32(WORD, 1, 8) == 255
887 || EXTRACTED32(WORD, 1, 31) == 0) {
888 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
889 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
890 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
891 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
892 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
895 error("DOUBLE - unknown case\n");
900 # Convert 64bit single to 32bit double
901 unsigned32::function::SINGLE:unsigned64 FRS
903 if (EXTRACTED64(FRS, 1, 11) > 896
904 || EXTRACTED64(FRS, 1, 63) == 0) {
905 /* no denormalization required (includes Zero/Infinity/NaN) */
906 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
907 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
909 else if (874 <= EXTRACTED64(FRS, 1, 11)
910 && EXTRACTED64(FRS, 1, 11) <= 896) {
911 /* denormalization required */
912 int sign = EXTRACTED64(FRS, 0, 0);
913 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
914 unsigned64 frac = (BIT64(0)
915 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
916 /* denormalize the operand */
918 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
921 WORD = (INSERTED32(sign, 0, 0)
922 | INSERTED32(0x00, 1, 8)
923 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
926 WORD = 0x0; /* ??? */
931 # round 64bit double to 64bit but single
932 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
933 /* comparisons ignore u bits */
936 int lsb = EXTRACTED64(*frac_grx, 23, 23);
937 int gbit = EXTRACTED64(*frac_grx, 24, 24);
938 int rbit = EXTRACTED64(*frac_grx, 25, 25);
939 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
940 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
941 if (lsb == 1 && gbit == 1) inc = 1;
942 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
943 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
945 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
946 if (sign == 0 && gbit == 1) inc = 1;
947 if (sign == 0 && rbit == 1) inc = 1;
948 if (sign == 0 && xbit == 1) inc = 1;
950 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
951 if (sign == 1 && gbit == 1) inc = 1;
952 if (sign == 1 && rbit == 1) inc = 1;
953 if (sign == 1 && xbit == 1) inc = 1;
955 /* work out addition in low 25 bits of out */
956 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
957 *frac_grx = INSERTED64(out, 0, 23);
958 if (out & BIT64(64 - 23 - 1 - 1)) {
959 *frac_grx = (BIT64(0) |
960 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
963 /* frac_grx[24:52] = 0 already */
965 FPSCR_SET_FI(gbit || rbit || xbit);
969 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
971 if (round_mode == fpscr_rn_round_to_nearest) {
972 if (*frac64 == 1 && gbit == 1) inc = 1;
973 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
974 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
976 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
977 if (sign == 0 && gbit == 1) inc = 1;
978 if (sign == 0 && rbit == 1) inc = 1;
979 if (sign == 0 && xbit == 1) inc = 1;
981 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
982 if (sign == 1 && gbit == 1) inc = 1;
983 if (sign == 1 && rbit == 1) inc = 1;
984 if (sign == 1 && xbit == 1) inc = 1;
986 /* frac[0:64] = frac[0:64} + inc */
987 *frac += (*frac64 && inc ? 1 : 0);
988 *frac64 = (*frac64 + inc) & 0x1;
990 FPSCR_SET_FI(gbit | rbit | xbit);
993 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
996 int lsb = EXTRACTED64(*frac, 52, 52);
997 int gbit = EXTRACTED64(*frac, 53, 53);
998 int rbit = EXTRACTED64(*frac, 54, 54);
999 int xbit = EXTRACTED64(*frac, 55, 55);
1000 if (round_mode == fpscr_rn_round_to_nearest) {
1001 if (lsb == 1 && gbit == 1) inc = 1;
1002 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1003 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1005 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1006 if (sign == 0 && gbit == 1) inc = 1;
1007 if (sign == 0 && rbit == 1) inc = 1;
1008 if (sign == 0 && xbit == 1) inc = 1;
1010 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1011 if (sign == 1 && gbit == 1) inc = 1;
1012 if (sign == 1 && rbit == 1) inc = 1;
1013 if (sign == 1 && xbit == 1) inc = 1;
1015 /* frac//carry_out = frac + inc */
1016 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1017 carry_out = EXTRACTED64(*frac, 0, 0);
1019 if (carry_out == 1) *exp = *exp + 1;
1021 FPSCR_SET_FI(gbit | rbit | xbit);
1022 FPSCR_SET_XX(FPSCR & fpscr_fi);
1025 # conversion of FP to integer
1026 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
1029 unsigned64 frac = 0;
1034 int sign = EXTRACTED64(frb, 0, 0);
1035 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1036 goto Infinity_Operand;
1037 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1039 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1041 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
1042 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1043 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1044 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1045 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1048 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1049 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1052 gbit = 0, rbit = 0, xbit = 0;
1053 for (i = 1; i <= 63 - exp; i++) {
1057 frac64 = EXTRACTED64(frac, 63, 63);
1058 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1060 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1061 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1064 frac += (frac64 ? 1 : 0);
1065 frac64 = (frac64 + 1) & 0x1;
1067 if (tgt_precision == 32 /* can ignore frac64 in compare */
1068 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1070 if (tgt_precision == 64 /* can ignore frac64 in compare */
1071 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1073 if (tgt_precision == 32 /* can ignore frac64 in compare */
1074 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1076 if (tgt_precision == 64 /* can ignore frac64 in compare */
1077 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1079 FPSCR_SET_XX(FPSCR & fpscr_fi);
1080 if (tgt_precision == 32)
1081 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1082 if (tgt_precision == 64)
1083 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1084 /*FPSCR[fprf] = undefined */
1090 FPSCR_OR_VX(fpscr_vxcvi);
1091 if ((FPSCR & fpscr_ve) == 0) {
1092 if (tgt_precision == 32) {
1093 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1094 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1097 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1098 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1100 /* FPSCR[FPRF] = undefined */
1107 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1108 if ((FPSCR & fpscr_ve) == 0) {
1109 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1110 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1111 /* FPSCR[fprf] = undefined */
1118 FPSCR_OR_VX(fpscr_vxcvi);
1119 if ((FPSCR & fpscr_ve) == 0) {
1120 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1121 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1122 /* FPSCR[fprf] = undefined */
1129 FPSCR_OR_VX(fpscr_vxcvi);
1130 if ((FPSCR & fpscr_ve) == 0) {
1131 if (tgt_precision == 32) {
1132 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1133 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1136 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1137 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1139 /* FPSCR[fprf] = undefined */
1145 # extract out raw fields of a FP number
1146 int::function::sign:unsigned64 FRS
1147 return (MASKED64(FRS, 0, 0)
1150 int::function::biased_exp:unsigned64 frs, int single
1152 return EXTRACTED64(frs, 1, 8);
1154 return EXTRACTED64(frs, 1, 11);
1155 unsigned64::function::fraction:unsigned64 frs, int single
1157 return EXTRACTED64(frs, 9, 31);
1159 return EXTRACTED64(frs, 12, 63);
1161 # a number?, each of the below return +1 or -1 (based on sign bit)
1163 int::function::is_nor:unsigned64 frs, int single
1164 int exp = biased_exp(frs, single);
1166 && exp <= (single ? 254 : 2046));
1167 int::function::is_zero:unsigned64 FRS
1168 return (MASKED64(FRS, 1, 63) == 0
1171 int::function::is_den:unsigned64 frs, int single
1172 int exp = biased_exp(frs, single);
1173 unsigned64 frac = fraction(frs, single);
1174 return (exp == 0 && frac != 0
1177 int::function::is_inf:unsigned64 frs, int single
1178 int exp = biased_exp(frs, single);
1179 int frac = fraction(frs, single);
1180 return (exp == (single ? 255 : 2047) && frac == 0
1183 int::function::is_NaN:unsigned64 frs, int single
1184 int exp = biased_exp(frs, single);
1185 int frac = fraction(frs, single);
1186 return (exp == (single ? 255 : 2047) && frac != 0
1189 int::function::is_SNaN:unsigned64 frs, int single
1190 return (is_NaN(frs, single)
1191 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1194 int::function::is_QNaN:unsigned64 frs, int single
1195 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1196 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1197 return *(double*)fra < *(double*)frb;
1198 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1199 return *(double*)fra > *(double*)frb;
1200 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1201 return *(double*)fra == *(double*)frb;
1204 # which quiet nan should become the result
1205 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1207 if (is_NaN(fra, single))
1209 else if (is_NaN(frb, single))
1210 if (instruction_is_frsp)
1211 frt = MASKED64(frb, 0, 34);
1214 else if (is_NaN(frc, single))
1216 else if (generate_qnan)
1217 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1219 error("select_qnan - default reached\n");
1223 # detect invalid operation
1224 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1226 if ((check & fpscr_vxsnan)
1227 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1228 FPSCR_OR_VX(fpscr_vxsnan);
1231 if ((check & fpscr_vxisi)
1232 && (is_inf(fra, single) && is_inf(frb, single))
1233 && ((negate && sign(fra) != sign(frb))
1234 || (!negate && sign(fra) == sign(frb)))) {
1235 /*FIXME: don't handle inf-inf VS inf+-inf */
1236 FPSCR_OR_VX(fpscr_vxisi);
1239 if ((check & fpscr_vxidi)
1240 && (is_inf(fra, single) && is_inf(frb, single))) {
1241 FPSCR_OR_VX(fpscr_vxidi);
1244 if ((check & fpscr_vxzdz)
1245 && (is_zero(fra) && is_zero(frb))) {
1246 FPSCR_OR_VX(fpscr_vxzdz);
1249 if ((check & fpscr_vximz)
1250 && (is_zero(fra) && is_inf(frb, single))) {
1251 FPSCR_OR_VX(fpscr_vximz);
1254 if ((check & fpscr_vxvc)
1255 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1256 FPSCR_OR_VX(fpscr_vxvc);
1259 if ((check & fpscr_vxsoft)) {
1260 FPSCR_OR_VX(fpscr_vxsoft);
1263 if ((check & fpscr_vxsqrt)
1265 FPSCR_OR_VX(fpscr_vxsqrt);
1268 /* if ((check && fpscr_vxcvi) {
1269 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1270 FPSCR_OR_VX(fpscr_vxcvi);
1280 # handle case of invalid operation
1281 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
1282 if (FPSCR & fpscr_ve) {
1283 /* invalid operation exception enabled */
1287 /* fpscr_FPRF unchanged */
1290 /* invalid operation exception disabled */
1291 if (instruction_is_convert_to_64bit) {
1294 else if (instruction_is_convert_to_32bit) {
1297 else { /* arrith, frsp */
1298 *frt = select_qnan(fra, frb, frc,
1299 instruction_is_frsp, 0/*generate*/, single);
1302 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1310 # I.2.4.1 Branch Instructions
1312 0.18,6.LI,30.AA,31.LK:I:t::Branch
1313 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1314 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1315 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1316 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1317 if (AA) NIA = IEA(EXTS(LI_0b00));
1318 else NIA = IEA(CIA + EXTS(LI_0b00));
1319 if (LK) LR = (spreg)CIA+4;
1320 model_branches(cpu_model(processor), 1);
1322 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
1323 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1324 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1325 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1326 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1327 int M, ctr_ok, cond_ok, succeed;
1329 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1330 if (is_64bit_implementation && is_64bit_mode) M = 0;
1332 if (!BO{2}) CTR = CTR - 1;
1333 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1334 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1335 if (ctr_ok && cond_ok) {
1336 if (AA) NIA = IEA(EXTS(BD_0b00));
1337 else NIA = IEA(CIA + EXTS(BD_0b00));
1342 if (LK) LR = (spreg)IEA(CIA + 4);
1343 model_branches(cpu_model(processor), succeed);
1346 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1347 reverse = EXTS(BD_0b00) < 0;
1348 } else { /* branch prediction bit not set */
1349 reverse = EXTS(BD_0b00) >= 0;
1351 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1354 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
1355 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1356 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1357 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1358 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1359 int M, ctr_ok, cond_ok, succeed;
1360 if (is_64bit_implementation && is_64bit_mode) M = 0;
1363 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1364 if (!BO{2}) CTR = CTR - 1;
1365 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1366 cond_ok = BO{0} || (CR{BI} == BO{1});
1367 if (ctr_ok && cond_ok) {
1373 if (LK) LR = (spreg)IEA(CIA + 4);
1374 model_branches(cpu_model(processor), succeed);
1376 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1378 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
1379 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1380 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1381 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1382 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1383 int cond_ok, succeed;
1385 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1386 cond_ok = BO{0} || (CR{BI} == BO{1});
1388 NIA = IEA(CTR_0b00);
1393 if (LK) LR = (spreg)IEA(CIA + 4);
1394 model_branches(cpu_model(processor), succeed);
1396 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1399 # I.2.4.2 System Call Instruction
1401 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
1402 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1403 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1404 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1405 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1406 model_serialize(my_index, cpu_model(processor));
1407 system_call_interrupt(processor, cia);
1410 # I.2.4.3 Condition Register Logical Instructions
1412 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1413 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1414 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1415 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1416 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1417 BLIT32(CR, BT, CR{BA} && CR{BB});
1418 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1420 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1421 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1422 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1423 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1424 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1425 BLIT32(CR, BT, CR{BA} || CR{BB});
1426 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1428 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1429 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1430 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1431 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1432 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1433 BLIT32(CR, BT, CR{BA} != CR{BB});
1434 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1436 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1437 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1438 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1439 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1440 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1441 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1442 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1444 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1445 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1446 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1447 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1448 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1449 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1450 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1452 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1453 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1454 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1455 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1456 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1457 BLIT32(CR, BT, CR{BA} == CR{BB});
1458 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1460 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1461 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1462 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1463 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1464 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1465 BLIT32(CR, BT, CR{BA} && !CR{BB});
1466 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1468 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1469 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1470 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1471 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1472 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1473 BLIT32(CR, BT, CR{BA} || !CR{BB});
1474 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1477 # I.2.4.4 Condition Register Field Instruction
1479 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1480 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1481 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1482 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1483 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1484 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1485 ppc_insn_cr1(my_index, processor, cpu_model(processor), BF, BFA);
1489 # I.3.3.2 Fixed-Point Load Instructions
1492 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1493 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1494 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1495 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1496 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1502 *rT = MEM(unsigned, EA, 1);
1504 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1506 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
1509 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1510 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1511 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1512 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1513 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1519 *rT = MEM(unsigned, EA, 1);
1521 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
1523 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
1525 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1526 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1527 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1528 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1529 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1531 if (RA == 0 || RA == RT)
1532 program_interrupt(processor, cia,
1533 illegal_instruction_program_interrupt);
1535 *rT = MEM(unsigned, EA, 1);
1537 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
1539 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1540 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1541 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1542 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1543 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1545 if (RA == 0 || RA == RT)
1546 program_interrupt(processor, cia,
1547 illegal_instruction_program_interrupt);
1549 *rT = MEM(unsigned, EA, 1);
1551 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
1553 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1554 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1555 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1556 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1557 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1563 *rT = MEM(unsigned, EA, 2);
1565 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1567 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
1569 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1570 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1571 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1572 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1573 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1579 *rT = MEM(unsigned, EA, 2);
1581 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
1583 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
1585 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1586 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1587 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1588 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1589 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1591 if (RA == 0 || RA == RT)
1592 program_interrupt(processor, cia,
1593 illegal_instruction_program_interrupt);
1595 *rT = MEM(unsigned, EA, 2);
1597 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
1599 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1600 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1601 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1602 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1603 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1605 if (RA == 0 || RA == RT)
1606 program_interrupt(processor, cia,
1607 illegal_instruction_program_interrupt);
1609 *rT = MEM(unsigned, EA, 2);
1611 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
1613 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1614 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1615 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1616 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1617 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1623 *rT = MEM(signed, EA, 2);
1625 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1627 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
1629 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1630 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1631 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1632 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1633 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1639 *rT = MEM(signed, EA, 2);
1641 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
1643 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
1645 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1646 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1647 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1648 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1649 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1651 if (RA == 0 || RA == RT)
1652 program_interrupt(processor, cia,
1653 illegal_instruction_program_interrupt);
1655 *rT = MEM(signed, EA, 2);
1656 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
1658 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1659 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1660 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1661 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1662 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1664 if (RA == 0 || RA == RT)
1665 program_interrupt(processor, cia,
1666 illegal_instruction_program_interrupt);
1668 *rT = MEM(signed, EA, 2);
1670 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
1672 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1673 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1674 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1675 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1676 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1682 *rT = MEM(unsigned, EA, 4);
1684 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1686 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
1688 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1689 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1690 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1691 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1692 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1698 *rT = MEM(unsigned, EA, 4);
1700 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
1702 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
1704 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1705 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1706 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1707 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1708 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1710 if (RA == 0 || RA == RT)
1711 program_interrupt(processor, cia,
1712 illegal_instruction_program_interrupt);
1714 *rT = MEM(unsigned, EA, 4);
1716 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
1718 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1719 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1720 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1721 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1722 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1724 if (RA == 0 || RA == RT)
1725 program_interrupt(processor, cia,
1726 illegal_instruction_program_interrupt);
1728 *rT = MEM(unsigned, EA, 4);
1730 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
1732 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1735 # if (RA == 0) b = 0;
1737 # EA = b + EXTS(DS_0b00);
1738 # *rT = MEM(signed, EA, 4);
1740 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1743 # if (RA == 0) b = 0;
1746 # *rT = MEM(signed, EA, 4);
1748 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1750 # if (RA == 0 || RA == RT)
1751 # program_interrupt(processor, cia
1752 # illegal_instruction_program_interrupt);
1754 # *rT = MEM(signed, EA, 4);
1757 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1760 # if (RA == 0) b = 0;
1762 # EA = b + EXTS(DS_0b00);
1763 # *rT = MEM(unsigned, EA, 8);
1765 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1768 # if (RA == 0) b = 0;
1771 # *rT = MEM(unsigned, EA, 8);
1773 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1775 # if (RA == 0 || RA == RT)
1776 # program_interrupt(processor, cia
1777 # illegal_instruction_program_interrupt);
1778 # EA = *rA + EXTS(DS_0b00);
1779 # *rT = MEM(unsigned, EA, 8);
1782 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1784 # if (RA == 0 || RA == RT)
1785 # program_interrupt(processor, cia
1786 # illegal_instruction_program_interrupt);
1788 # *rT = MEM(unsigned, EA, 8);
1794 # I.3.3.3 Fixed-Point Store Instructions
1797 0.38,6.RS,11.RA,16.D:D:::Store Byte
1798 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1799 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1800 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1801 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1809 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
1811 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
1813 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1814 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1815 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1816 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1817 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1825 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
1827 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
1829 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1830 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1831 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1832 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1833 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1836 program_interrupt(processor, cia,
1837 illegal_instruction_program_interrupt);
1841 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
1843 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1844 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1845 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1846 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1847 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1850 program_interrupt(processor, cia,
1851 illegal_instruction_program_interrupt);
1855 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
1857 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1858 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1859 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1860 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1861 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1869 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
1871 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
1873 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1874 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1875 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1876 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1877 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1885 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
1887 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
1889 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1890 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1891 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1892 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1893 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1896 program_interrupt(processor, cia,
1897 illegal_instruction_program_interrupt);
1901 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
1903 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1904 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1905 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1906 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1907 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1910 program_interrupt(processor, cia,
1911 illegal_instruction_program_interrupt);
1915 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
1917 0.36,6.RS,11.RA,16.D:D:::Store Word
1918 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1919 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1920 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1921 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1929 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
1931 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
1933 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
1934 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1935 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1936 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1937 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1945 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
1947 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
1949 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
1950 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1951 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1952 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1953 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1956 program_interrupt(processor, cia,
1957 illegal_instruction_program_interrupt);
1961 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
1963 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
1964 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1965 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1966 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1967 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1970 program_interrupt(processor, cia,
1971 illegal_instruction_program_interrupt);
1975 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
1977 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
1980 # if (RA == 0) b = 0;
1982 # EA = b + EXTS(DS_0b00);
1983 # STORE(EA, 8, *rS);
1984 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
1987 # if (RA == 0) b = 0;
1990 # STORE(EA, 8, *rS);
1991 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
1994 # program_interrupt(processor, cia
1995 # illegal_instruction_program_interrupt);
1996 # EA = *rA + EXTS(DS_0b00);
1997 # STORE(EA, 8, *rS);
1999 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2002 # program_interrupt(processor, cia
2003 # illegal_instruction_program_interrupt);
2005 # STORE(EA, 8, *rS);
2010 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2013 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2014 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2015 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2016 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2017 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2023 *rT = SWAP_2(MEM(unsigned, EA, 2));
2025 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2027 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2029 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2030 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2031 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2032 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2033 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2039 *rT = SWAP_4(MEM(unsigned, EA, 4));
2041 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2043 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2045 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2046 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2047 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2048 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2049 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2055 STORE(EA, 2, SWAP_2(*rS));
2057 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2059 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2061 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2062 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2063 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2064 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2065 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2071 STORE(EA, 4, SWAP_4(*rS));
2073 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2075 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2079 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2082 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
2084 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2088 # I.3.3.6 Fixed-Point Move Assist Instructions
2091 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
2093 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2095 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
2097 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2101 # I.3.3.7 Storage Synchronization Instructions
2103 # HACK: Rather than monitor addresses looking for a reason
2104 # to cancel a reservation. This code instead keeps
2105 # a copy of the data read from memory. Before performing
2106 # a store, the memory area is checked to see if it has
2108 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2109 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2110 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2111 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2112 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2119 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2120 RESERVE_DATA = MEM(unsigned, EA, 4);
2123 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2130 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2131 RESERVE_DATA = MEM(unsigned, EA, 8);
2134 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2135 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2136 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2137 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2138 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2145 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2146 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2148 CR_SET_XER_SO(0, cr_i_zero);
2151 /* ment to randomly to store, we never do! */
2152 CR_SET_XER_SO(0, 0);
2157 CR_SET_XER_SO(0, 0);
2159 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2166 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2167 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2169 CR_SET_XER_SO(0, cr_i_zero);
2172 /* ment to randomly to store, we never do */
2173 CR_SET_XER_SO(0, 0);
2178 CR_SET_XER_SO(0, 0);
2181 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2182 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2183 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2184 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2185 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2190 # I.3.3.9 Fixed-Point Arithmetic Instructions
2193 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
2194 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2195 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2196 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2197 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2200 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2203 *rT = *rA + EXTS(SI);
2204 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2207 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2208 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2209 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2210 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2211 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2213 *rT = EXTS(SI) << 16;
2214 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2217 *rT = *rA + (EXTS(SI) << 16);
2218 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2221 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2222 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2223 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2224 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2225 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2228 ALU_END(*rT, 0/*CA*/, OE, Rc);
2229 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2231 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2232 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2233 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2234 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2235 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2240 ALU_END(*rT, 0/*CA*/, OE, Rc);
2241 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2243 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2244 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2245 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2246 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2247 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2250 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2251 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2253 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2254 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2255 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2256 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2257 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2260 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2261 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 1/*Rc*/);
2263 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2264 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2265 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2266 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2267 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2272 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2273 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2275 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2276 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2277 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2278 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2279 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2282 ALU_END(*rT, 1/*CA*/, OE, Rc);
2283 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2285 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2286 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2287 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2288 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2289 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2290 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2295 ALU_END(*rT, 1/*CA*/, OE, Rc);
2296 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2298 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2299 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2300 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2301 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2302 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2306 ALU_END(*rT, 1/*CA*/, OE, Rc);
2307 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2309 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2310 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2311 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2312 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2313 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2318 ALU_END(*rT, 1/*CA*/, OE, Rc);
2319 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2321 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2322 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2323 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2324 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2325 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2329 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2331 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2332 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2333 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2334 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2335 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2340 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2342 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2343 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2344 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2345 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2346 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2349 ALU_END(*rT, 1/*CA*/, OE, Rc);
2350 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2352 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2353 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2354 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2355 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2356 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2360 ALU_END(*rT, 1/*CA*/, OE, Rc);
2361 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2363 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2364 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2365 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2366 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2367 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2371 ALU_END(*rT,0/*CA*/,OE,Rc);
2372 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2374 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2375 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2376 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2377 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2378 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2379 signed_word prod = *rA * EXTS(SI);
2381 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2383 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2385 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2386 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2387 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2388 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2389 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2390 signed64 a = (signed32)(*rA);
2391 signed64 b = (signed32)(*rB);
2392 signed64 prod = a * b;
2393 signed_word t = prod;
2395 if (t != prod && OE)
2396 XER |= (xer_overflow | xer_summary_overflow);
2397 CR0_COMPARE(t, 0, Rc);
2398 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2400 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2402 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2403 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2404 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2405 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2406 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2407 signed64 a = (signed32)(*rA);
2408 signed64 b = (signed32)(*rB);
2409 signed64 prod = a * b;
2410 signed_word t = EXTRACTED64(prod, 0, 31);
2412 CR0_COMPARE(t, 0, Rc);
2413 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2415 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2417 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2418 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2419 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2420 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2421 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2422 unsigned64 a = (unsigned32)(*rA);
2423 unsigned64 b = (unsigned32)(*rB);
2424 unsigned64 prod = a * b;
2425 signed_word t = EXTRACTED64(prod, 0, 31);
2427 CR0_COMPARE(t, 0, Rc);
2428 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2430 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2432 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2433 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2434 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2435 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2436 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2437 signed64 dividend = (signed32)(*rA);
2438 signed64 divisor = (signed32)(*rB);
2439 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2440 || (dividend == 0x80000000 && divisor == -1)) {
2442 XER |= (xer_overflow | xer_summary_overflow);
2443 CR0_COMPARE(0, 0, Rc);
2446 signed64 quotent = dividend / divisor;
2448 CR0_COMPARE((signed_word)quotent, 0, Rc);
2450 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2452 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2454 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2455 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2456 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2457 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2458 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2459 unsigned64 dividend = (unsigned32)(*rA);
2460 unsigned64 divisor = (unsigned32)(*rB);
2463 XER |= (xer_overflow | xer_summary_overflow);
2464 CR0_COMPARE(0, 0, Rc);
2467 unsigned64 quotent = dividend / divisor;
2469 CR0_COMPARE((signed_word)quotent, 0, Rc);
2471 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2475 # I.3.3.10 Fixed-Point Compare Instructions
2478 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2479 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2480 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2481 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2482 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2483 if (!is_64bit_mode && L)
2484 program_interrupt(processor, cia,
2485 illegal_instruction_program_interrupt);
2488 signed_word b = EXTS(SI);
2493 CR_COMPARE(BF, a, b);
2495 ppc_insn_int1_cr(my_index, processor, cpu_model(processor), BF, rA);
2497 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2498 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2499 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2500 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2501 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2502 if (!is_64bit_mode && L)
2503 program_interrupt(processor, cia,
2504 illegal_instruction_program_interrupt);
2516 CR_COMPARE(BF, a, b);
2518 ppc_insn_int2_cr(my_index, processor, cpu_model(processor), BF, rA, rB);
2520 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2521 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2522 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2523 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2524 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2525 if (!is_64bit_mode && L)
2526 program_interrupt(processor, cia,
2527 illegal_instruction_program_interrupt);
2530 unsigned_word b = UI;
2532 a = MASKED(*rA, 32, 63);
2535 CR_COMPARE(BF, a, b);
2537 ppc_insn_int1_cr(my_index, processor, cpu_model(processor), BF, rA);
2539 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2540 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2541 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2542 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2543 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2544 if (!is_64bit_mode && L)
2545 program_interrupt(processor, cia,
2546 illegal_instruction_program_interrupt);
2551 a = MASKED(*rA, 32, 63);
2552 b = MASKED(*rB, 32, 63);
2558 CR_COMPARE(BF, a, b);
2560 ppc_insn_int2_cr(my_index, processor, cpu_model(processor), BF, rA, rB);
2564 # I.3.3.11 Fixed-Point Trap Instructions
2567 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2569 program_interrupt(processor, cia,
2570 illegal_instruction_program_interrupt);
2572 signed_word a = *rA;
2573 signed_word b = EXTS(SI);
2574 if ((a < b && TO{0})
2576 || (a == b && TO{2})
2577 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2578 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2580 program_interrupt(processor, cia,
2581 trap_program_interrupt);
2584 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2585 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2586 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2587 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2588 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2589 signed_word a = EXTENDED(*rA);
2590 signed_word b = EXTS(SI);
2591 if ((a < b && TO{0})
2593 || (a == b && TO{2})
2594 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2595 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2597 program_interrupt(processor, cia,
2598 trap_program_interrupt);
2600 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2602 program_interrupt(processor, cia,
2603 illegal_instruction_program_interrupt);
2605 signed_word a = *rA;
2606 signed_word b = *rB;
2607 if ((a < b && TO{0})
2609 || (a == b && TO{2})
2610 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2611 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2613 program_interrupt(processor, cia,
2614 trap_program_interrupt);
2617 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2618 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2619 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2620 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2621 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2622 signed_word a = EXTENDED(*rA);
2623 signed_word b = EXTENDED(*rB);
2624 if (TO == 12 && rA == rB) {
2625 ITRACE(trace_breakpoint, ("breakpoint\n"));
2626 cpu_halt(processor, cia, was_trap, 0);
2628 else if ((a < b && TO{0})
2630 || (a == b && TO{2})
2631 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2632 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2634 program_interrupt(processor, cia,
2635 trap_program_interrupt);
2638 # I.3.3.12 Fixed-Point Logical Instructions
2641 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2642 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2643 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2644 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2645 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2647 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2648 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 1/*Rc*/);
2650 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2651 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2652 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2653 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2654 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2655 *rA = *rS & (UI << 16);
2656 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2657 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 1/*Rc*/);
2659 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2660 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2661 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2662 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2663 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2665 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
2667 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2668 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2669 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2670 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2671 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2672 *rA = *rS | (UI << 16);
2673 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
2675 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2676 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2677 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2678 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2679 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2681 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
2683 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2684 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2685 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2686 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2687 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2688 *rA = *rS ^ (UI << 16);
2689 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
2691 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
2692 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2693 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2694 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2695 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2697 CR0_COMPARE(*rA, 0, Rc);
2698 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
2700 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
2701 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2702 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2703 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2704 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2706 CR0_COMPARE(*rA, 0, Rc);
2707 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
2709 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
2710 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2711 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2712 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2713 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2715 CR0_COMPARE(*rA, 0, Rc);
2716 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
2718 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
2719 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2720 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2721 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2722 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2724 CR0_COMPARE(*rA, 0, Rc);
2725 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
2727 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
2728 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2729 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2730 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2731 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2733 CR0_COMPARE(*rA, 0, Rc);
2734 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
2736 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
2737 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2738 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2739 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2740 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2741 # *rA = ~(*rS ^ *rB); /* A === B */
2742 # CR0_COMPARE(*rA, 0, Rc);
2744 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
2745 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2746 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2747 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2748 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2750 CR0_COMPARE(*rA, 0, Rc);
2751 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
2753 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
2754 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2755 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2756 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2757 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2759 CR0_COMPARE(*rA, 0, Rc);
2760 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
2762 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
2763 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2764 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2765 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2766 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2767 *rA = (signed_word)(signed8)*rS;
2768 CR0_COMPARE(*rA, 0, Rc);
2769 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
2771 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
2772 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2773 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2774 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2775 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2776 *rA = (signed_word)(signed16)*rS;
2777 CR0_COMPARE(*rA, 0, Rc);
2778 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
2780 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2781 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2782 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2783 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2784 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2785 # *rA = (signed_word)(signed32)*rS;
2786 # CR0_COMPARE(*rA, 0, Rc);
2788 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2790 # unsigned64 mask = BIT64(0);
2791 # unsigned64 source = *rS;
2792 # while (!(source & mask) && mask != 0) {
2797 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2799 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
2800 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2801 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2802 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2803 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2805 unsigned32 mask = BIT32(0);
2806 unsigned32 source = *rS;
2807 while (!(source & mask) && mask != 0) {
2812 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2816 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2819 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
2820 # long n = (sh_5 << 4) | sh_0_4;
2821 # unsigned_word r = ROTL64(*rS, n);
2822 # long b = (mb_5 << 4) | mb_0_4;
2823 # unsigned_word m = MASK(b, 63);
2824 # signed_word result = r & m;
2826 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2828 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
2829 # long n = (sh_5 << 4) | sh_0_4;
2830 # unsigned_word r = ROTL64(*rS, n);
2831 # long e = (me_5 << 4) | me_0_4;
2832 # unsigned_word m = MASK(0, e);
2833 # signed_word result = r & m;
2835 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2837 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
2838 # long n = (sh_5 << 4) | sh_0_4;
2839 # unsigned_word r = ROTL64(*rS, n);
2840 # long b = (mb_5 << 4) | mb_0_4;
2841 # unsigned_word m = MASK(0, (64-n));
2842 # signed_word result = r & m;
2844 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2846 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2847 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2848 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2849 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2850 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2853 unsigned32 r = ROTL32(s, n);
2854 unsigned32 m = MASK(MB+32, ME+32);
2855 signed_word result = r & m;
2857 CR0_COMPARE(result, 0, Rc);
2859 ("n=%d, s=0x%x, r=0x%x, m=0x%x, result=0x%x, cr=0x%x\n",
2860 n, s, r, m, result, CR));
2861 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
2863 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2864 # long n = MASKED(*rB, 58, 63);
2865 # unsigned_word r = ROTL64(*rS, n);
2866 # long b = (mb_5 << 4) | mb_0_4;
2867 # unsigned_word m = MASK(b, 63);
2868 # signed_word result = r & m;
2870 # CR0_COMPARE(result, 0, Rc);
2872 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2873 # long n = MASKED(*rB, 58, 63);
2874 # unsigned_word r = ROTL64(*rS, n);
2875 # long e = (me_5 << 4) | me_0_4;
2876 # unsigned_word m = MASK(0, e);
2877 # signed_word result = r & m;
2879 # CR0_COMPARE(result, 0, Rc);
2881 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2882 # long n = MASKED(*rB, 59, 63);
2883 # unsigned32 r = ROTL32(*rS, n);
2884 # unsigned32 m = MASK(MB+32, ME+32);
2885 # signed_word result = r & m;
2887 # CR0_COMPARE(result, 0, Rc);
2889 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
2890 # long n = (sh_5 << 4) | sh_0_4;
2891 # unsigned_word r = ROTL64(*rS, n);
2892 # long b = (mb_5 << 4) | mb_0_4;
2893 # unsigned_word m = MASK(b, (64-n));
2894 # signed_word result = (r & m) | (*rA & ~m)
2896 # CR0_COMPARE(result, 0, Rc);
2898 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2899 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2900 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2901 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2902 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2904 unsigned32 r = ROTL32(*rS, n);
2905 unsigned32 m = MASK(MB+32, ME+32);
2906 signed_word result = (r & m) | (*rA & ~m);
2908 ITRACE(trace_alu, (": n=%d *rS=0x%x r=0x%x m=0x%x result=0x%x\n",
2909 n, *rS, r, m, result));
2910 CR0_COMPARE(result, 0, Rc);
2911 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
2914 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2916 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2917 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2918 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2919 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2920 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2921 int n = MASKED(*rB, 59, 63);
2922 unsigned32 source = *rS;
2923 signed_word shifted;
2925 shifted = (source << n);
2929 CR0_COMPARE(shifted, 0, Rc);
2931 ("n=%d, source=0x%x, shifted=0x%x\n",
2932 n, source, shifted));
2933 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
2935 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
2937 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
2938 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2939 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2940 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2941 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2942 int n = MASKED(*rB, 59, 63);
2943 unsigned32 source = *rS;
2944 signed_word shifted;
2946 shifted = (source >> n);
2950 CR0_COMPARE(shifted, 0, Rc);
2952 ("n=%d, source=0x%x, shifted=0x%x\n",
2953 n, source, shifted));
2954 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
2956 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
2958 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
2959 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2960 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2961 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2962 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2964 signed_word r = ROTL32(*rS, /*64*/32-n);
2965 signed_word m = MASK(n+32, 63);
2966 int S = MASKED(*rS, 32, 32);
2967 signed_word shifted = (r & m) | (S ? ~m : 0);
2969 if (S && ((r & ~m) & MASK(32, 63)) != 0)
2973 CR0_COMPARE(shifted, 0, Rc);
2974 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
2976 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
2978 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
2979 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2980 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2981 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2982 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2983 int n = MASKED(*rB, 58, 63);
2984 int shift = (n >= 31 ? 31 : n);
2985 signed32 source = (signed32)*rS; /* signed to keep sign bit */
2986 signed32 shifted = source >> shift;
2987 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
2988 *rA = (signed_word)shifted; /* if 64bit will sign extend */
2989 if (source < 0 && (source & mask))
2993 CR0_COMPARE(shifted, 0, Rc);
2994 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
2997 # I.3.3.14 Move to/from System Register Instructions
3000 0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3001 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3002 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3003 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3004 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3005 int n = (spr{5:9} << 5) | spr{0:4};
3006 if (spr{0} && IS_PROBLEM_STATE(processor))
3007 program_interrupt(processor, cia,
3008 privileged_instruction_program_interrupt);
3009 else if (!spr_is_valid(n)
3010 || spr_is_readonly(n))
3011 program_interrupt(processor, cia,
3012 illegal_instruction_program_interrupt);
3014 spreg new_val = (spr_length(n) == 64
3016 : MASKED(*rS, 32, 63));
3017 /* HACK - time base registers need to be updated immediatly */
3018 if (WITH_TIME_BASE) {
3022 cpu_set_time_base(processor,
3023 (MASKED64(cpu_get_time_base(processor), 32, 63)
3024 | INSERTED64(new_val, 0, 31)));
3027 cpu_set_time_base(processor,
3028 (MASKED64(cpu_get_time_base(processor), 0, 31)
3029 | INSERTED64(new_val, 32, 63)));
3032 cpu_set_decrementer(processor, new_val);
3043 ppc_insn_to_spr(my_index, processor, cpu_model(processor), n, rS);
3045 0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3046 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3047 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3048 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3049 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3050 int n = (spr{5:9} << 5) | spr{0:4};
3051 if (spr{0} && IS_PROBLEM_STATE(processor))
3052 program_interrupt(processor, cia,
3053 privileged_instruction_program_interrupt);
3054 else if (!spr_is_valid(n))
3055 program_interrupt(processor, cia,
3056 illegal_instruction_program_interrupt);
3058 /* HACK - some SPR's need to get their value extracted specially */
3061 ppc_insn_from_spr(my_index, processor, cpu_model(processor), rT, n);
3063 # FIXME: 604 uses SCIU{1,2} if only one bit is being set
3064 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3065 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3066 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3067 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3068 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3073 unsigned_word mask = 0;
3075 for (f = 0; f < 8; f++) {
3076 if (FXM & (0x80 >> f))
3077 mask |= (0xf << 4*(7-f));
3079 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3081 ppc_insn_mtcr(my_index, processor, cpu_model(processor), rS);
3083 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3085 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3086 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3087 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3088 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3089 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3090 *rT = (unsigned32)CR;
3091 ppc_insn_mfcr(my_index, processor, cpu_model(processor), rT);
3094 # I.4.6.2 Floating-Point Load Instructions
3097 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3098 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3099 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3100 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3101 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3107 *frT = DOUBLE(MEM(unsigned, EA, 4));
3109 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3110 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3111 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3112 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3113 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3119 *frT = DOUBLE(MEM(unsigned, EA, 4));
3121 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3122 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3123 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3124 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3125 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3128 program_interrupt(processor, cia,
3129 illegal_instruction_program_interrupt);
3131 *frT = DOUBLE(MEM(unsigned, EA, 4));
3134 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3135 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3136 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3137 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3138 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3141 program_interrupt(processor, cia,
3142 illegal_instruction_program_interrupt);
3144 *frT = DOUBLE(MEM(unsigned, EA, 4));
3147 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3148 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3149 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3150 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3151 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3157 *frT = MEM(unsigned, EA, 8);
3159 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3160 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3161 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3162 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3163 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3169 *frT = MEM(unsigned, EA, 8);
3171 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3172 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3173 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3174 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3175 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3178 program_interrupt(processor, cia,
3179 illegal_instruction_program_interrupt);
3181 *frT = MEM(unsigned, EA, 8);
3184 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3185 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3186 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3187 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3188 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3191 program_interrupt(processor, cia,
3192 illegal_instruction_program_interrupt);
3194 *frT = MEM(unsigned, EA, 8);
3199 # I.4.6.3 Floating-Point Store Instructions
3202 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3203 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3204 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3205 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3206 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3212 STORE(EA, 4, SINGLE(*frS));
3214 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3215 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3216 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3217 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3218 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3224 STORE(EA, 4, SINGLE(*frS));
3226 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3227 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3228 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3229 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3230 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3233 program_interrupt(processor, cia,
3234 illegal_instruction_program_interrupt);
3236 STORE(EA, 4, SINGLE(*frS));
3239 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3240 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3241 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3242 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3243 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3246 program_interrupt(processor, cia,
3247 illegal_instruction_program_interrupt);
3249 STORE(EA, 4, SINGLE(*frS));
3252 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3253 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3254 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3255 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3256 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3264 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3265 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3266 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3267 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3268 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3276 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3277 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3278 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3279 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3280 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3283 program_interrupt(processor, cia,
3284 illegal_instruction_program_interrupt);
3289 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3290 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3291 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3292 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3293 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3296 program_interrupt(processor, cia,
3297 illegal_instruction_program_interrupt);
3304 # I.4.6.4 Floating-Point Move Instructions
3307 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3308 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3309 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3310 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3311 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3315 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3316 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3317 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3318 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3319 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3320 *frT = *frB ^ BIT64(0);
3323 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3324 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3325 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3326 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3327 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3328 *frT = *frB & ~BIT64(0);
3331 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3332 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3333 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3334 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3335 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3336 *frT = *frB | BIT64(0);
3342 # I.4.6.5 Floating-Point Arithmetic Instructions
3345 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3346 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3347 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3348 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3349 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3351 if (is_invalid_operation(processor, cia,
3353 fpscr_vxsnan | fpscr_vxisi,
3356 invalid_arithemetic_operation(processor, cia,
3358 0, /*instruction_is_frsp*/
3359 0, /*instruction_is_convert_to_64bit*/
3360 0, /*instruction_is_convert_to_32bit*/
3361 0); /*single-precision*/
3365 double s = *(double*)frA + *(double*)frB;
3370 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3371 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3372 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3373 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3374 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3376 if (is_invalid_operation(processor, cia,
3378 fpscr_vxsnan | fpscr_vxisi,
3381 invalid_arithemetic_operation(processor, cia,
3383 0, /*instruction_is_frsp*/
3384 0, /*instruction_is_convert_to_64bit*/
3385 0, /*instruction_is_convert_to_32bit*/
3386 1); /*single-precision*/
3390 float s = *(double*)frA + *(double*)frB;
3395 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3396 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3397 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3398 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3399 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3401 if (is_invalid_operation(processor, cia,
3403 fpscr_vxsnan | fpscr_vxisi,
3406 invalid_arithemetic_operation(processor, cia,
3408 0, /*instruction_is_frsp*/
3409 0, /*instruction_is_convert_to_64bit*/
3410 0, /*instruction_is_convert_to_32bit*/
3411 0); /*single-precision*/
3415 double s = *(double*)frA - *(double*)frB;
3420 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3421 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3422 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3423 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3424 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3426 if (is_invalid_operation(processor, cia,
3428 fpscr_vxsnan | fpscr_vxisi,
3431 invalid_arithemetic_operation(processor, cia,
3433 0, /*instruction_is_frsp*/
3434 0, /*instruction_is_convert_to_64bit*/
3435 0, /*instruction_is_convert_to_32bit*/
3436 1); /*single-precision*/
3440 float s = *(double*)frA - *(double*)frB;
3445 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3446 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3447 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3448 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3449 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3451 if (is_invalid_operation(processor, cia,
3453 fpscr_vxsnan | fpscr_vximz,
3456 invalid_arithemetic_operation(processor, cia,
3458 0, /*instruction_is_frsp*/
3459 0, /*instruction_is_convert_to_64bit*/
3460 0, /*instruction_is_convert_to_32bit*/
3461 0); /*single-precision*/
3465 double s = *(double*)frA * *(double*)frC;
3470 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3471 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3472 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3473 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3474 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3476 if (is_invalid_operation(processor, cia,
3478 fpscr_vxsnan | fpscr_vximz,
3481 invalid_arithemetic_operation(processor, cia,
3483 0, /*instruction_is_frsp*/
3484 0, /*instruction_is_convert_to_64bit*/
3485 0, /*instruction_is_convert_to_32bit*/
3486 1); /*single-precision*/
3490 float s = *(double*)frA * *(double*)frC;
3495 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3496 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3497 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3498 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3499 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3501 if (is_invalid_operation(processor, cia,
3503 fpscr_vxsnan | fpscr_vxzdz,
3506 invalid_arithemetic_operation(processor, cia,
3508 0, /*instruction_is_frsp*/
3509 0, /*instruction_is_convert_to_64bit*/
3510 0, /*instruction_is_convert_to_32bit*/
3511 0); /*single-precision*/
3515 double s = *(double*)frA / *(double*)frB;
3520 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3521 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3522 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3523 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3524 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3526 if (is_invalid_operation(processor, cia,
3528 fpscr_vxsnan | fpscr_vxzdz,
3531 invalid_arithemetic_operation(processor, cia,
3533 0, /*instruction_is_frsp*/
3534 0, /*instruction_is_convert_to_64bit*/
3535 0, /*instruction_is_convert_to_32bit*/
3536 1); /*single-precision*/
3540 float s = *(double*)frA / *(double*)frB;
3545 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3546 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3547 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3548 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3549 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3551 double product; /*HACK! - incorrectly loosing precision ... */
3552 /* compute the multiply */
3553 if (is_invalid_operation(processor, cia,
3555 fpscr_vxsnan | fpscr_vximz,
3558 invalid_arithemetic_operation(processor, cia,
3559 (unsigned64*)&product, *frA, 0, *frC,
3560 0, /*instruction_is_frsp*/
3561 0, /*instruction_is_convert_to_64bit*/
3562 0, /*instruction_is_convert_to_32bit*/
3563 0); /*single-precision*/
3567 product = *(double*)frA * *(double*)frC;
3569 /* compute the add */
3570 if (is_invalid_operation(processor, cia,
3572 fpscr_vxsnan | fpscr_vxisi,
3575 invalid_arithemetic_operation(processor, cia,
3576 frT, product, *frB, 0,
3577 0, /*instruction_is_frsp*/
3578 0, /*instruction_is_convert_to_64bit*/
3579 0, /*instruction_is_convert_to_32bit*/
3580 0); /*single-precision*/
3584 double s = product + *(double*)frB;
3589 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3590 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3591 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3592 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3593 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3595 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3596 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3597 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3598 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3599 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3601 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
3602 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3603 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3604 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3605 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3607 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
3608 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3609 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3610 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3611 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3613 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
3614 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3615 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3616 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3617 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3619 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
3620 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3621 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3622 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3623 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3625 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
3626 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3627 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3628 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3629 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3633 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
3636 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
3637 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3638 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3639 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3640 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3643 unsigned64 frac_grx;
3644 /* split off cases for what to do */
3645 if (EXTRACTED64(*frB, 1, 11) < 897
3646 && EXTRACTED64(*frB, 1, 63) > 0) {
3647 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
3648 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
3650 if (EXTRACTED64(*frB, 1, 11) > 1150
3651 && EXTRACTED64(*frB, 1, 11) < 2047) {
3652 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3653 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
3655 if (EXTRACTED64(*frB, 1, 11) > 896
3656 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
3657 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
3658 if (EXTRACTED64(*frB, 1, 11) == 2047) {
3659 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
3660 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
3661 if (EXTRACTED64(*frB, 12, 12) == 0
3662 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
3665 Disabled_Exponent_Underflow:
3666 sign = EXTRACTED64(*frB, 0, 0);
3667 if (EXTRACTED64(*frB, 1, 11) == 0) {
3669 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3671 if (EXTRACTED64(*frB, 1, 11) > 0) {
3672 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3673 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3675 Denormalize_Operand:
3676 /* G|R|X == zero from above */
3677 while (exp < -126) {
3679 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
3680 | MASKED64(frac_grx, 55, 55));
3682 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
3683 Round_Single(processor, sign, &exp, &frac_grx);
3684 FPSCR_SET_XX(FPSCR & fpscr_fi);
3685 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
3686 *frT = INSERTED64(sign, 0, 0);
3687 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3688 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3690 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
3691 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
3692 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3693 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3695 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
3696 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
3697 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
3699 /*Normalize_Operand:*/
3700 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3702 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3704 *frT = (INSERTED64(sign, 0, 0)
3705 | INSERTED64(exp + 1023, 1, 11)
3706 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3709 Enabled_Exponent_Underflow:
3711 sign = EXTRACTED64(*frB, 0, 0);
3712 if (EXTRACTED64(*frB, 1, 11) == 0) {
3714 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3716 if (EXTRACTED64(*frB, 1, 11) > 0) {
3717 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3718 frac_grx = (BIT64(0) |
3719 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
3721 /*Normalize_Operand:*/
3722 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3724 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3726 Round_Single(processor, sign, &exp, &frac_grx);
3727 FPSCR_SET_XX(FPSCR & fpscr_fi);
3729 *frT = (INSERTED64(sign, 0, 0)
3730 | INSERTED64(exp + 1023, 1, 11)
3731 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3732 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3733 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3735 Disabled_Exponent_Overflow:
3737 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
3738 if (EXTRACTED64(*frB, 0, 0) == 0) {
3739 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
3740 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3742 if (EXTRACTED64(*frB, 0, 0) == 1) {
3743 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
3744 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3747 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
3748 if (EXTRACTED64(*frB, 0, 0) == 0) {
3749 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
3750 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3752 if (EXTRACTED64(*frB, 0, 0) == 1) {
3753 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
3754 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3757 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
3758 if (EXTRACTED64(*frB, 0, 0) == 0) {
3759 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
3760 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3762 if (EXTRACTED64(*frB, 0, 0) == 1) {
3763 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
3764 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3767 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
3768 if (EXTRACTED64(*frB, 0, 0) == 0) {
3769 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
3770 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3772 if (EXTRACTED64(*frB, 0, 0) == 1) {
3773 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
3774 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3777 /* FPSCR[FR] <- undefined */
3781 Enabled_Exponent_Overflow:
3782 sign = EXTRACTED64(*frB, 0, 0);
3783 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3784 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3785 Round_Single(processor, sign, &exp, &frac_grx);
3786 FPSCR_SET_XX(FPSCR & fpscr_fi);
3790 *frT = (INSERTED64(sign, 0, 0)
3791 | INSERTED64(exp + 1023, 1, 11)
3792 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3793 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3794 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3798 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3799 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3805 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3806 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3811 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
3812 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
3817 FPSCR_OR_VX(fpscr_vxsnan);
3818 if ((FPSCR & fpscr_ve) == 0) {
3819 *frT = (MASKED64(*frB, 0, 11)
3821 | MASKED64(*frB, 13, 34));
3822 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
3828 sign = EXTRACTED64(*frB, 0, 0);
3829 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3830 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3831 Round_Single(processor, sign, &exp, &frac_grx);
3832 FPSCR_SET_XX(FPSCR & fpscr_fi);
3833 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3834 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
3835 *frT = (INSERTED64(sign, 0, 0)
3836 | INSERTED64(exp + 1023, 1, 11)
3837 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3838 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3839 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3843 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
3845 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
3847 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
3849 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
3850 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3851 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3852 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3853 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3855 convert_to_integer(processor, cia,
3857 fpscr_rn_round_towards_zero, 32);
3860 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
3861 int sign = EXTRACTED64(*frB, 0, 0);
3863 unsigned64 frac = *frB;
3864 if (frac == 0) goto Zero_Operand;
3865 if (sign == 1) frac = ~frac + 1;
3866 while (EXTRACTED64(frac, 0, 0) == 0) {
3867 /*??? do the loop 0 times if (FRB) = max negative integer */
3868 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
3871 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
3872 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3873 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3874 *frT = (INSERTED64(sign, 0, 0)
3875 | INSERTED64(exp + 1023, 1, 11)
3876 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
3882 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3889 # I.4.6.7 Floating-Point Compare Instructions
3892 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
3893 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3894 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3895 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3896 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3899 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3900 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3901 else if (is_less_than(frA, frB))
3902 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3903 else if (is_greater_than(frA, frB))
3904 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3906 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3908 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3909 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
3910 FPSCR_OR_VX(fpscr_vxsnan);
3913 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
3914 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3915 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3916 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3917 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3920 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3921 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3922 else if (is_less_than(frA, frB))
3923 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3924 else if (is_greater_than(frA, frB))
3925 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3927 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3929 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3930 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
3931 FPSCR_OR_VX(fpscr_vxsnan);
3932 if ((FPSCR & fpscr_ve) == 0)
3933 FPSCR_OR_VX(fpscr_vxvc);
3935 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
3936 FPSCR_OR_VX(fpscr_vxvc);
3942 # I.4.6.8 Floating-Point Status and Control Register Instructions
3945 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
3947 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
3949 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
3951 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
3953 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
3955 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
3959 # I.A.1.1 Floating-Point Store Instruction
3961 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
3964 # I.A.1.2 Floating-Point Arithmetic Instructions
3967 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
3969 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
3971 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
3973 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
3976 # I.A.1.3 Floating-Point Select Instruction
3979 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
3983 # II.3.2 Cache Management Instructions
3986 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
3987 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3988 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3989 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3990 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
3991 /* blindly flush all instruction cache entries */
3992 #if WITH_IDECODE_CACHE_SIZE
3993 cpu_flush_icache(processor);
3996 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
3997 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3998 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3999 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4000 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4001 cpu_synchronize_context(processor);
4005 # II.3.2.2 Data Cache Instructions
4008 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4009 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4010 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4011 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4012 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4013 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4015 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4016 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4017 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4018 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4019 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4020 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4022 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4023 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4024 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4025 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4026 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4027 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4029 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4030 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4031 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4032 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4033 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4034 TRACE(trace_tbd,("Data Cache Block Store\n"));
4036 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4037 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4038 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4039 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4040 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4041 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4044 # II.3.3 Enforce In-order Execution of I/O Instruction
4047 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4048 /* Since this model has no instruction overlap
4049 this instruction need do nothing */
4052 # II.4.1 Time Base Instructions
4055 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4056 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4057 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4058 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4059 int n = (tbr{5:9} << 5) | tbr{0:4};
4061 if (is_64bit_implementation) *rT = TB;
4062 else *rT = EXTRACTED64(TB, 32, 63);
4064 else if (n == 269) {
4065 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4066 else *rT = EXTRACTED64(TB, 0, 31);
4069 program_interrupt(processor, cia,
4070 illegal_instruction_program_interrupt);
4074 # III.2.3.1 System Linkage Instructions
4077 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4078 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4079 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4080 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4081 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4082 if (IS_PROBLEM_STATE(processor)) {
4083 program_interrupt(processor, cia,
4084 privileged_instruction_program_interrupt);
4087 MSR = (MASKED(SRR1, 0, 32)
4088 | MASKED(SRR1, 37, 41)
4089 | MASKED(SRR1, 48, 63));
4090 NIA = MASKED(SRR0, 0, 61);
4091 cpu_synchronize_context(processor);
4095 # III.3.4.1 Move to/from System Register Instructions
4098 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
4099 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
4100 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4101 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4102 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4103 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4104 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4105 if (IS_PROBLEM_STATE(processor))
4106 program_interrupt(processor, cia,
4107 privileged_instruction_program_interrupt);
4111 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4112 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4113 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4114 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4115 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4116 if (IS_PROBLEM_STATE(processor))
4117 program_interrupt(processor, cia,
4118 privileged_instruction_program_interrupt);
4124 # III.4.11.1 Cache Management Instructions
4127 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4128 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4129 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4130 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4131 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4132 if (IS_PROBLEM_STATE(processor))
4133 program_interrupt(processor, cia,
4134 privileged_instruction_program_interrupt);
4136 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4139 # III.4.11.2 Segment Register Manipulation Instructions
4142 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4143 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4144 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4145 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4146 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4147 if (IS_PROBLEM_STATE(processor))
4148 program_interrupt(processor, cia,
4149 privileged_instruction_program_interrupt);
4153 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4154 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4155 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4156 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4157 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4158 if (IS_PROBLEM_STATE(processor))
4159 program_interrupt(processor, cia,
4160 privileged_instruction_program_interrupt);
4162 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4164 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4165 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4166 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4167 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4168 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4169 if (IS_PROBLEM_STATE(processor))
4170 program_interrupt(processor, cia,
4171 privileged_instruction_program_interrupt);
4175 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4176 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4177 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4178 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4179 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4180 if (IS_PROBLEM_STATE(processor))
4181 program_interrupt(processor, cia,
4182 privileged_instruction_program_interrupt);
4184 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4188 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4191 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4193 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4195 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4197 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4199 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4203 # III.A.1.2 External Access Instructions
4206 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4208 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed