Count each type of conditional branch
[deliverable/binutils-gdb.git] / sim / ppc / ppc-instructions
1 #
2 # This file is part of the program psim.
3 #
4 # Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
5 #
6 # --
7 #
8 # The pseudo-code that appears below, translated into C, was copied
9 # by Andrew Cagney of Moss Vale, Australia.
10 #
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.
15 #
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.
19 #
20 # --
21 #
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.
26 #
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.
31 #
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.
35 #
36 # --
37 #
38 #
39 # Fields:
40 #
41 # 1 Instruction format as a `start-bit,content' pairs.
42 # the content is one of a digit, field name or `/' (aka.0)
43 #
44 # 2 Format specifier
45 #
46 # 3 Flags: 64 - 64bit only
47 # f - floating point enabled required
48 #
49 # 4 short name
50 #
51 # 5 Description
52 #
53 #
54 # For flags marked 'model', the fields are interpreted as follows:
55 #
56 # 1 Not used
57 #
58 # 2 Not used
59 #
60 # 3 "macro"
61 #
62 # 4 String name for model
63 #
64 # 5 Specific CPU model, must be an identifier
65 #
66 # 6 Comma separated list of functional units
67
68 \f
69 # PowerPC models
70 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
71 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
72 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
73 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0
74
75 # Flags for model.h
76 ::model-data:::
77 typedef enum _ppc_function_unit {
78 PPC_UNIT_BAD, /* unknown function unit */
79 PPC_UNIT_IU, /* integer unit (601/603 style) */
80 PPC_UNIT_SRU, /* system register unit (601/603 style) */
81 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
82 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
83 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
84 PPC_UNIT_FPU, /* floating point unit */
85 PPC_UNIT_LSU, /* load/store unit */
86 PPC_UNIT_BPU, /* branch unit */
87 nr_ppc_function_units
88 } ppc_function_unit;
89
90 /* Structure to hold timing information on a per instruction basis */
91 struct _model_time {
92 ppc_function_unit first_unit; /* first functional unit this insn could use */
93 ppc_function_unit second_unit; /* second functional unit this insn could use */
94 signed16 issue; /* # cycles before function unit can process other insns */
95 signed16 done; /* # cycles before insn is done */
96 unsigned32 flags; /* any flags that are needed */
97 };
98
99 /* Register mappings in status masks */
100 #define PPC_CR_REG 0 /* start of CR0 .. CR7 */
101 #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */
102
103 #define PPC_NO_SPR (-1) /* flag for no SPR register */
104
105 /* Structure for each functional unit that is busy */
106 typedef struct _model_busy model_busy;
107 struct _model_busy {
108 model_busy *next; /* next function unit */
109 ppc_function_unit unit; /* function unit name */
110 unsigned32 int_busy; /* int registers that are busy */
111 unsigned32 fp_busy; /* floating point registers that are busy */
112 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
113 signed16 spr_busy; /* SPR register that is busy or PPC_NO_SPR */
114 signed8 issue; /* # of cycles until unit can accept another insn */
115 signed8 done; /* # of cycles until insn is done */
116 };
117
118 /* Structure to hold the current state information for the simulated CPU model */
119 struct _model_data {
120 cpu *processor; /* point back to processor */
121 const char *name; /* model name */
122 const model_time *timing; /* timing information */
123 model_busy *busy_list; /* list of busy function units */
124 model_busy *free_list; /* list of model_busy structs not in use */
125 count_type nr_cycles; /* # cycles */
126 count_type nr_branches; /* # branches */
127 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
128 count_type nr_branch_predict_trues; /* # branches predicted correctly */
129 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
130 count_type nr_branch_conditional[32]; /* # of each type of bc */
131 count_type nr_stalls_data; /* # of stalls for data */
132 count_type nr_stalls_unit; /* # of stalls waiting for a function unit */
133 count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */
134 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
135 unsigned32 int_busy; /* int registers that are busy */
136 unsigned32 fp_busy; /* floating point registers that are busy */
137 unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */
138 unsigned8 spr_busy[nr_of_sprs]; /* SPR registers that are busy */
139 unsigned8 busy[nr_ppc_function_units]; /* whether a function is busy or not */
140 };
141
142 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
143 "unknown functional unit instruction",
144 "integer functional unit instruction",
145 "system register functional unit instruction",
146 "1st single cycle integer functional unit instruction",
147 "2nd single cycle integer functional unit instruction",
148 "multiple cycle integer functional unit instruction",
149 "floating point functional unit instruction",
150 "load/store functional unit instruction",
151 "branch functional unit instruction",
152 };
153
154 STATIC_MODEL const char *const ppc_branch_conditional_name[32] = {
155 "branch if --CTR != 0 and condition is FALSE", /* 0000y */
156 "branch if --CTR != 0 and condition is FALSE, reverse branch likely",
157 "branch if --CTR == 0 and condition is FALSE", /* 0001y */
158 "branch if --CTR == 0 and condition is FALSE, reverse branch likely",
159 "branch if the condition is FALSE", /* 001zy */
160 "branch if the condition is FALSE, reverse branch likely",
161 "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */
162 "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)",
163 "branch if --CTR != 0 and condition is TRUE", /* 0100y */
164 "branch if --CTR != 0 and condition is TRUE, reverse branch likely",
165 "branch if --CTR == 0 and condition is TRUE", /* 0101y */
166 "branch if --CTR == 0 and condition is TRUE, reverse branch likely",
167 "branch if the condition is TRUE", /* 011zy */
168 "branch if the condition is TRUE, reverse branch likely",
169 "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */
170 "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)",
171 "branch if --CTR != 0", /* 1z00y */
172 "branch if --CTR != 0, reverse branch likely",
173 "branch if --CTR == 0", /* 1z01y */
174 "branch if --CTR == 0, reverse branch likely",
175 "branch always", /* 1z1zz */
176 "branch always (ignored bit 5 set to 1)",
177 "branch always (ignored bit 4 set to 1)", /* 1z1zz */
178 "branch always (ignored bits 4,5 set to 1)",
179 "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */
180 "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)",
181 "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */
182 "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)",
183 "branch always (ignored bit 1 set to 1)", /* 1z1zz */
184 "branch always (ignored bits 1,5 set to 1)",
185 "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */
186 "branch always (ignored bits 1,4,5 set to 1)",
187 };
188
189 \f
190 # Trace releasing resources
191 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
192 int i;
193 TRACE(trace_model,("done, %s\n", ppc_function_unit_name[busy->unit]));
194 if (busy->int_busy) {
195 for(i = 0; i < 32; i++) {
196 if (((1 << i) & busy->int_busy) != 0) {
197 TRACE(trace_model, ("Register r%d is now available.\n", i));
198 }
199 }
200 }
201 if (busy->fp_busy) {
202 for(i = 0; i < 32; i++) {
203 if (((1 << i) & busy->fp_busy) != 0) {
204 TRACE(trace_model, ("Register f%d is now available.\n", i));
205 }
206 }
207 }
208 if (busy->cr_fpscr_busy) {
209 for(i = 0; i < 8; i++) {
210 if (((1 << i) & busy->cr_fpscr_busy) != 0) {
211 TRACE(trace_model, ("Register cr%d is now available.\n", i));
212 }
213 }
214 if (busy->cr_fpscr_busy & 0x100)
215 TRACE(trace_model, ("Register fpscr is now available.\n"));
216 }
217 if (busy->spr_busy != PPC_NO_SPR)
218 TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
219
220 # Trace waiting for registers to become available
221 void::model-static::model_trace_busy_p:model_data *model_ptr, unsigned32 int_busy, unsigned32 fp_busy, unsigned32 cr_or_fpscr_busy, int spr_busy
222 int i;
223 if (int_busy) {
224 int_busy &= model_ptr->int_busy;
225 for(i = 0; i < 32; i++) {
226 if (((1 << i) & int_busy) != 0) {
227 TRACE(trace_model, ("Waiting for register r%d.\n", i));
228 }
229 }
230 }
231 if (fp_busy) {
232 fp_busy &= model_ptr->fp_busy;
233 for(i = 0; i < 32; i++) {
234 if (((1 << i) & fp_busy) != 0) {
235 TRACE(trace_model, ("Waiting for register f%d.\n", i));
236 }
237 }
238 }
239 if (cr_or_fpscr_busy) {
240 cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy;
241 for(i = 0; i < 8; i++) {
242 if (((1 << i) & cr_or_fpscr_busy) != 0) {
243 TRACE(trace_model, ("Waiting for register cr%d.\n", i));
244 }
245 }
246 if (cr_or_fpscr_busy & 0x100)
247 TRACE(trace_model, ("Waiting for register fpscr.\n"));
248 }
249 if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy])
250 TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy)));
251 \f
252 # Advance state to next cycle, releasing any registers allocated
253 void::model-internal::model_new_cycle:model_data *model_ptr
254 model_busy *cur_busy = model_ptr->busy_list;
255 model_busy *free_list = model_ptr->free_list;
256 model_busy *next_busy = (model_busy *)0;
257 model_busy *next;
258
259 model_ptr->nr_cycles++;
260 for ( ; cur_busy; cur_busy = next) {
261 next = cur_busy->next;
262 if (--cur_busy->done <= 0) { /* function unit done, release registers */
263 model_ptr->int_busy &= ~cur_busy->int_busy;
264 model_ptr->fp_busy &= ~cur_busy->fp_busy;
265 model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
266 if (cur_busy->spr_busy != PPC_NO_SPR)
267 model_ptr->spr_busy[cur_busy->spr_busy] = 0;
268
269 if (WITH_TRACE && ppc_trace[trace_model])
270 model_trace_release(model_ptr, cur_busy);
271
272 model_ptr->busy[cur_busy->unit] = 0;
273 cur_busy->next = free_list;
274 free_list = cur_busy;
275 }
276 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
277 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
278 model_ptr->busy[cur_busy->unit] = 0;
279 cur_busy->next = next_busy;
280 next_busy = cur_busy;
281 }
282 else {
283 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
284 ppc_function_unit_name[cur_busy->unit],
285 cur_busy->issue,
286 cur_busy->done));
287 cur_busy->next = next_busy;
288 next_busy = cur_busy;
289 }
290 }
291
292 model_ptr->busy_list = next_busy;
293 model_ptr->free_list = free_list;
294
295 # Mark a function unit as busy, return the busy structure
296 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
297 model_busy *busy;
298
299 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
300
301 if (!model_ptr->free_list) {
302 busy = ZALLOC(model_busy);
303 }
304 else {
305 busy = model_ptr->free_list;
306 model_ptr->free_list = busy->next;
307 }
308 busy->next = model_ptr->busy_list;
309 busy->unit = unit;
310 busy->issue = issue;
311 busy->done = done;
312 busy->int_busy = 0;
313 busy->fp_busy = 0;
314 busy->cr_fpscr_busy = 0;
315 busy->spr_busy = PPC_NO_SPR;
316 model_ptr->busy_list = busy;
317 model_ptr->busy[unit] = 1;
318 model_ptr->nr_units[unit]++;
319 return busy;
320 \f
321 # Make a given integer register busy
322 void::model-internal::model_make_int_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
323 TRACE(trace_model,("Marking register r%d as busy\n", regno));
324 busy_ptr->int_busy |= (1 << regno);
325 model_ptr->int_busy |= (1 << regno);
326
327 # Make a given floating point register busy
328 void::model-internal::model_make_fp_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
329 TRACE(trace_model,("Marking register f%d as busy\n", regno));
330 busy_ptr->fp_busy |= (1 << regno);
331 model_ptr->fp_busy |= (1 << regno);
332
333 # Make a given CR register busy
334 void::model-internal::model_make_cr_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
335 TRACE(trace_model,("Marking register cr%d as busy\n", regno));
336 busy_ptr->cr_fpscr_busy |= (1 << regno);
337 model_ptr->cr_fpscr_busy |= (1 << regno);
338
339 # Make a given SPR register busy
340 void::model-internal::model_make_spr_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
341 TRACE(trace_model,("Marking register %s as busy\n", spr_name(regno)));
342 busy_ptr->spr_busy = regno;
343 model_ptr->spr_busy[regno] = 1;
344
345 \f
346 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
347 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
348 ppc_function_unit first_unit = time_ptr->first_unit;
349 ppc_function_unit second_unit = time_ptr->second_unit;
350 int stall_increment = 0;
351
352 for (;;) {
353 if (!model_ptr->busy[first_unit])
354 return model_make_busy(model_ptr, first_unit,
355 model_ptr->timing[index].issue,
356 model_ptr->timing[index].done);
357
358 if (!model_ptr->busy[second_unit])
359 return model_make_busy(model_ptr, second_unit,
360 model_ptr->timing[index].issue,
361 model_ptr->timing[index].done);
362
363 TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
364 model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
365 stall_increment = 1;
366 model_new_cycle(model_ptr);
367 }
368
369 # Serialize the processor, waiting for all instructions to drain out before adding an instruction.
370 void::model-function::model_serialize:itable_index index, model_data *model_ptr
371 while (model_ptr->busy_list) {
372 TRACE(trace_model,("waiting for pipeline to empty\n"));
373 model_ptr->nr_stalls_serialize++;
374 model_new_cycle(model_ptr);
375 }
376 (void) model_make_busy(model_ptr,
377 model_ptr->timing[index].first_unit,
378 model_ptr->timing[index].issue,
379 model_ptr->timing[index].done);
380
381 # Wait for a CR to become unbusy
382 void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
383 unsigned u;
384 unsigned32 cr_mask;
385 int cr_var = 0;
386 for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 )
387 cr_var++;
388
389 cr_mask = (1 << cr_var);
390 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
391 TRACE(trace_model,("waiting for CR %d\n", cr_var));
392 model_ptr->nr_stalls_data++;
393 model_new_cycle(model_ptr);
394 }
395
396 # Schedule an instruction that takes 2 integer input registers and produces an output register & possibly sets CR0
397 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
398 registers *cpu_regs = cpu_registers(processor);
399 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
400 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
401 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
402 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RD);
403 model_busy *busy_ptr;
404
405 if (!WITH_MODEL_ISSUE)
406 return;
407
408 else if (!Rc) {
409 if ((model_ptr->int_busy & int_mask) != 0) {
410 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
411
412 while ((model_ptr->int_busy & int_mask) != 0) {
413 if (WITH_TRACE && ppc_trace[trace_model])
414 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
415
416 model_ptr->nr_stalls_data++;
417 model_new_cycle(model_ptr);
418 }
419 }
420
421 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
422 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
423 return;
424 }
425
426 else {
427 const unsigned32 cr_mask = (1 << 0);
428
429 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
430 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
431
432 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
433 if (WITH_TRACE && ppc_trace[trace_model])
434 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
435
436 model_ptr->nr_stalls_data++;
437 model_new_cycle(model_ptr);
438 }
439 }
440
441 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
442 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
443 model_make_cr_reg_busy(model_ptr, busy_ptr, 0);
444 return;
445 }
446
447 # Schedule an instruction that takes 1 integer input registers and produces an output register & possibly sets CR0
448 void::model-function::ppc_insn_int1:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA, unsigned Rc
449 registers *cpu_regs = cpu_registers(processor);
450 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
451 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
452 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RD);
453 model_busy *busy_ptr;
454
455 if (!WITH_MODEL_ISSUE)
456 return;
457
458 else if (!Rc) {
459 if ((model_ptr->int_busy & int_mask) != 0) {
460 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
461
462 while ((model_ptr->int_busy & int_mask) != 0) {
463 if (WITH_TRACE && ppc_trace[trace_model])
464 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
465
466 model_ptr->nr_stalls_data++;
467 model_new_cycle(model_ptr);
468 }
469 }
470
471 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
472 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
473 return;
474 }
475
476 else {
477 const unsigned32 cr_mask = (1 << 0);
478
479 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
480 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
481
482 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
483 if (WITH_TRACE && ppc_trace[trace_model])
484 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
485
486 model_ptr->nr_stalls_data++;
487 model_new_cycle(model_ptr);
488 }
489 }
490
491 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
492 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
493 model_make_cr_reg_busy(model_ptr, busy_ptr, 0);
494 return;
495 }
496
497 # Schedule an instruction that takes no integer input registers and produces an output register & possibly sets CR0
498 void::model-function::ppc_insn_int0:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, unsigned Rc
499 registers *cpu_regs = cpu_registers(processor);
500 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
501 const unsigned32 int_mask = (1 << ppc_RD);
502 model_busy *busy_ptr;
503
504 if (!WITH_MODEL_ISSUE)
505 return;
506
507 else if (!Rc) {
508 while ((model_ptr->int_busy & int_mask) != 0) {
509 if (WITH_TRACE && ppc_trace[trace_model])
510 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
511
512 model_ptr->nr_stalls_data++;
513 model_new_cycle(model_ptr);
514 }
515
516 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
517 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
518 return;
519 }
520
521 else {
522 const unsigned32 cr_mask = (1 << 0);
523
524 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
525 if (WITH_TRACE && ppc_trace[trace_model])
526 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
527
528 model_ptr->nr_stalls_data++;
529 model_new_cycle(model_ptr);
530 }
531
532 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
533 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
534 model_make_cr_reg_busy(model_ptr, busy_ptr, 0);
535 return;
536 }
537
538 # Schedule an instruction that takes 2 integer input registers and produces an output register & updates a second register
539 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
540 if (!WITH_MODEL_ISSUE)
541 return;
542
543 else {
544 registers *cpu_regs = cpu_registers(processor);
545 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
546 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
547 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
548 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RD);
549 model_busy *busy_ptr;
550
551 if ((model_ptr->int_busy & int_mask) != 0) {
552 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
553
554 while ((model_ptr->int_busy & int_mask) != 0) {
555 if (WITH_TRACE && ppc_trace[trace_model])
556 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
557
558 model_ptr->nr_stalls_data++;
559 model_new_cycle(model_ptr);
560 }
561 }
562
563 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
564 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
565 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
566 }
567
568 # Schedule an instruction that takes 1 integer input registers and produces an output register & updates the other register
569 void::model-function::ppc_insn_int1_update:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, signed_word *rA
570 if (!WITH_MODEL_ISSUE)
571 return;
572
573 else {
574 registers *cpu_regs = cpu_registers(processor);
575 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
576 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
577 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RD);
578 model_busy *busy_ptr;
579
580 if ((model_ptr->int_busy & int_mask) != 0) {
581 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
582
583 while ((model_ptr->int_busy & int_mask) != 0) {
584 if (WITH_TRACE && ppc_trace[trace_model])
585 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
586
587 model_ptr->nr_stalls_data++;
588 model_new_cycle(model_ptr);
589 }
590 }
591
592 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
593 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
594 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
595 }
596
597 # Schedule an instruction that takes 2 integer input registers and produces no output register
598 void::model-function::ppc_insn_int2_noout:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rA, signed_word *rB
599 if (!WITH_MODEL_ISSUE)
600 return;
601
602 else {
603 registers *cpu_regs = cpu_registers(processor);
604 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
605 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
606 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB);
607
608 if ((model_ptr->int_busy & int_mask) != 0) {
609 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
610
611 while ((model_ptr->int_busy & int_mask) != 0) {
612 if (WITH_TRACE && ppc_trace[trace_model])
613 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
614
615 model_ptr->nr_stalls_data++;
616 model_new_cycle(model_ptr);
617 }
618 }
619
620 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
621 }
622
623 # Schedule an instruction that takes 1 integer input registers and produces no output register
624 void::model-function::ppc_insn_int1_noout:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rA
625 if (!WITH_MODEL_ISSUE)
626 return;
627
628 else {
629 registers *cpu_regs = cpu_registers(processor);
630 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
631 const unsigned32 int_mask = (1 << ppc_RA);
632
633 if ((model_ptr->int_busy & int_mask) != 0) {
634 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
635
636 while ((model_ptr->int_busy & int_mask) != 0) {
637 if (WITH_TRACE && ppc_trace[trace_model])
638 model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
639
640 model_ptr->nr_stalls_data++;
641 model_new_cycle(model_ptr);
642 }
643 }
644
645 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
646 }
647
648 # Schedule an instruction that takes no input registers and produces no output
649 void::model-function::ppc_insn_int0_noout:itable_index index, cpu *processor, model_data *model_ptr
650 if (!WITH_MODEL_ISSUE)
651 return;
652
653 else {
654 (void) model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
655 }
656
657 # Schedule an instruction that takes 2 integer input registers and produces a CR output register
658 void::model-function::ppc_insn_int2_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, signed_word *rA, signed_word *rB
659 if (!WITH_MODEL_ISSUE)
660 return;
661
662 else {
663 registers *cpu_regs = cpu_registers(processor);
664 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
665 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
666 const unsigned32 int_mask = (1 << ppc_RA) | (1 << ppc_RB);
667 const unsigned32 cr_mask = (1 << CRD);
668 model_busy *busy_ptr;
669
670 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
671 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
672
673 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
674 if (WITH_TRACE && ppc_trace[trace_model])
675 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
676
677 model_ptr->nr_stalls_data++;
678 model_new_cycle(model_ptr);
679 }
680 }
681
682 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
683 model_make_cr_reg_busy(model_ptr, busy_ptr, CRD);
684 }
685
686 # Schedule an instruction that takes 1 integer input register and produces a CR output register
687 void::model-function::ppc_insn_int1_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, signed_word *rA
688 if (!WITH_MODEL_ISSUE)
689 return;
690
691 else {
692 registers *cpu_regs = cpu_registers(processor);
693 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
694 const unsigned32 int_mask = (1 << ppc_RA);
695 const unsigned32 cr_mask = (1 << CRD);
696 model_busy *busy_ptr;
697
698 if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
699 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
700
701 while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
702 if (WITH_TRACE && ppc_trace[trace_model])
703 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
704
705 model_ptr->nr_stalls_data++;
706 model_new_cycle(model_ptr);
707 }
708 }
709
710 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
711 model_make_cr_reg_busy(model_ptr, busy_ptr, CRD);
712 }
713
714 # Schedule an instruction that takes 3 floating point input registers and produces an output register & possibly sets CR1
715 void::model-function::ppc_insn_fp3:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, unsigned64 *rA, unsigned64 *rB, unsigned64 *rC, unsigned Rc
716 registers *cpu_regs = cpu_registers(processor);
717 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
718 const unsigned ppc_RB = (rB - &cpu_regs->fpr[0]);
719 const unsigned ppc_RC = (rC - &cpu_regs->fpr[0]);
720 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
721 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RC) | (1 << ppc_RD);
722 model_busy *busy_ptr;
723
724 if (!WITH_MODEL_ISSUE)
725 return;
726
727 else if (!Rc) {
728 if ((model_ptr->fp_busy & fp_mask) != 0) {
729 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
730
731 while ((model_ptr->fp_busy & fp_mask) != 0) {
732 if (WITH_TRACE && ppc_trace[trace_model])
733 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
734
735 model_ptr->nr_stalls_data++;
736 model_new_cycle(model_ptr);
737 }
738 }
739
740 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
741 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
742 return;
743 }
744
745 else {
746 const unsigned32 cr_mask = (1 << 1);
747 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
748 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
749
750 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
751 if (WITH_TRACE && ppc_trace[trace_model])
752 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
753
754 model_ptr->nr_stalls_data++;
755 model_new_cycle(model_ptr);
756 }
757 }
758
759 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
760 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
761 model_make_cr_reg_busy(model_ptr, busy_ptr, 1);
762 return;
763 }
764
765 # Schedule an instruction that takes 2 floating point input registers and produces an output register & possibly sets CR1
766 void::model-function::ppc_insn_fp2:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, unsigned64 *rA, unsigned64 *rB, unsigned Rc
767 registers *cpu_regs = cpu_registers(processor);
768 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
769 const unsigned ppc_RB = (rB - &cpu_regs->fpr[0]);
770 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
771 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RB) | (1 << ppc_RD);
772 model_busy *busy_ptr;
773
774 if (!WITH_MODEL_ISSUE)
775 return;
776
777 else if (!Rc) {
778 if ((model_ptr->fp_busy & fp_mask) != 0) {
779 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
780
781 while ((model_ptr->fp_busy & fp_mask) != 0) {
782 if (WITH_TRACE && ppc_trace[trace_model])
783 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
784
785 model_ptr->nr_stalls_data++;
786 model_new_cycle(model_ptr);
787 }
788 }
789
790 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
791 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
792 }
793
794 else {
795 const unsigned32 cr_mask = (1 << 1);
796
797 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
798 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
799
800 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
801 if (WITH_TRACE && ppc_trace[trace_model])
802 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
803
804 model_ptr->nr_stalls_data++;
805 model_new_cycle(model_ptr);
806 }
807 }
808
809 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
810 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
811 model_make_cr_reg_busy(model_ptr, busy_ptr, 1);
812 }
813
814 # Schedule an instruction that takes 1 floating point input registers and produces an output register & possibly sets CR1
815 void::model-function::ppc_insn_fp1:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, unsigned64 *rA, unsigned Rc
816 registers *cpu_regs = cpu_registers(processor);
817 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
818 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
819 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RD);
820 model_busy *busy_ptr;
821
822 if (!WITH_MODEL_ISSUE)
823 return;
824
825 else if (!Rc) {
826 if ((model_ptr->fp_busy & fp_mask) != 0) {
827 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
828
829 while ((model_ptr->fp_busy & fp_mask) != 0) {
830 if (WITH_TRACE && ppc_trace[trace_model])
831 model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
832
833 model_ptr->nr_stalls_data++;
834 model_new_cycle(model_ptr);
835 }
836 }
837
838 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
839 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
840 }
841
842 else {
843 const unsigned32 cr_mask = (1 << 1);
844
845 if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
846 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
847
848 while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
849 if (WITH_TRACE && ppc_trace[trace_model])
850 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
851
852 model_ptr->nr_stalls_data++;
853 model_new_cycle(model_ptr);
854 }
855 }
856
857 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
858 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
859 model_make_cr_reg_busy(model_ptr, busy_ptr, 1);
860 }
861
862 # Schedule an instruction that takes 1 floating point input register & 2 integer registers and does not produce an output
863 # (or takes 2 integer registers and produces an output in the floating point register)
864 void::model-function::ppc_insn_int2_fp1:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, signed_word *rA, signed_word *rB, int RD_is_output, int RA_is_update
865 if (!WITH_MODEL_ISSUE)
866 return;
867
868 else {
869 registers *cpu_regs = cpu_registers(processor);
870 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
871 const unsigned ppc_RB = (rB - &cpu_regs->gpr[0]);
872 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
873 const unsigned32 int_mask = (1 << ppc_RB) | ((ppc_RA == 0) ? 0 : (1 << ppc_RA));
874 const unsigned32 fp_mask = (1 << ppc_RD);
875 model_busy *busy_ptr;
876
877 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
878 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
879
880 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
881 if (WITH_TRACE && ppc_trace[trace_model])
882 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
883
884 model_ptr->nr_stalls_data++;
885 model_new_cycle(model_ptr);
886 }
887 }
888
889 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
890 if (RD_is_output)
891 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
892
893 if (RA_is_update)
894 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
895 }
896
897 # Schedule an instruction that takes 1 floating point input register & 1 integer register and does not produce an output
898 # (or takes 1 integer register and produces an output in the floating point register)
899 void::model-function::ppc_insn_int1_fp1:itable_index index, cpu *processor, model_data *model_ptr, unsigned64 *rD, signed_word *rA, int RD_is_output, int RA_is_update
900 if (!WITH_MODEL_ISSUE)
901 return;
902
903 else {
904 registers *cpu_regs = cpu_registers(processor);
905 const unsigned ppc_RA = (rA - &cpu_regs->gpr[0]);
906 const unsigned ppc_RD = (rD - &cpu_regs->fpr[0]);
907 const unsigned32 int_mask = ((ppc_RA == 0) ? 0 : (1 << ppc_RA));
908 const unsigned32 fp_mask = (1 << ppc_RD);
909 model_busy *busy_ptr;
910
911 if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
912 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
913
914 while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) {
915 if (WITH_TRACE && ppc_trace[trace_model])
916 model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR);
917
918 model_ptr->nr_stalls_data++;
919 model_new_cycle(model_ptr);
920 }
921 }
922
923 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
924 if (RD_is_output)
925 model_make_fp_reg_busy(model_ptr, busy_ptr, ppc_RD);
926
927 if (RA_is_update)
928 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RA);
929 }
930
931 # Schedule an instruction that takes 2 floating input registers and produces a CR output register
932 void::model-function::ppc_insn_fp2_cr:itable_index index, cpu *processor, model_data *model_ptr, unsigned CRD, unsigned64 *rA, unsigned64 *rB
933 if (!WITH_MODEL_ISSUE)
934 return;
935
936 else {
937 registers *cpu_regs = cpu_registers(processor);
938 const unsigned ppc_RA = (rA - &cpu_regs->fpr[0]);
939 const unsigned ppc_RB = (rB - &cpu_regs->fpr[0]);
940 const unsigned32 fp_mask = (1 << ppc_RA) | (1 << ppc_RB);
941 const unsigned32 cr_mask = (1 << CRD);
942 model_busy *busy_ptr;
943
944 if (((model_ptr->fp_busy & fp_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
945 model_new_cycle(model_ptr); /* don't count first dependency as a stall */
946
947 while (((model_ptr->fp_busy & fp_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
948 if (WITH_TRACE && ppc_trace[trace_model])
949 model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
950
951 model_ptr->nr_stalls_data++;
952 model_new_cycle(model_ptr);
953 }
954 }
955
956 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
957 model_make_cr_reg_busy(model_ptr, busy_ptr, CRD);
958 }
959
960 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
961 void::model-function::ppc_insn_from_spr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD, unsigned nSPR
962 if (!WITH_MODEL_ISSUE)
963 return;
964
965 else {
966 registers *cpu_regs = cpu_registers(processor);
967 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
968 const unsigned32 int_mask = (1 << ppc_RD);
969 model_busy *busy_ptr;
970
971 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
972 if (WITH_TRACE && ppc_trace[trace_model])
973 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
974
975 model_ptr->nr_stalls_data++;
976 model_new_cycle(model_ptr);
977 }
978
979 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
980 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
981 }
982
983 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
984 void::model-function::ppc_insn_to_spr:itable_index index, cpu *processor, model_data *model_ptr, unsigned nSPR, signed_word *rS
985 if (!WITH_MODEL_ISSUE)
986 return;
987
988 else {
989 registers *cpu_regs = cpu_registers(processor);
990 const unsigned ppc_RS = (rS - &cpu_regs->gpr[0]);
991 const unsigned32 int_mask = (1 << ppc_RS);
992 model_busy *busy_ptr;
993
994 while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
995 if (WITH_TRACE && ppc_trace[trace_model])
996 model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);
997
998 model_ptr->nr_stalls_data++;
999 model_new_cycle(model_ptr);
1000 }
1001
1002 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1003 model_make_spr_reg_busy(model_ptr, busy_ptr, nSPR);
1004 }
1005
1006 # Schedule a MFCR instruction that moves the CR into an integer regsiter
1007 void::model-function::ppc_insn_mfcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rD
1008 if (!WITH_MODEL_ISSUE)
1009 return;
1010
1011 else {
1012 registers *cpu_regs = cpu_registers(processor);
1013 const unsigned ppc_RD = (rD - &cpu_regs->gpr[0]);
1014 const unsigned32 int_mask = (1 << ppc_RD);
1015 const unsigned32 cr_mask = 0xff;
1016 model_busy *busy_ptr;
1017
1018 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
1019 if (WITH_TRACE && ppc_trace[trace_model])
1020 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
1021
1022 model_ptr->nr_stalls_data++;
1023 model_new_cycle(model_ptr);
1024 }
1025
1026 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1027 model_make_int_reg_busy(model_ptr, busy_ptr, ppc_RD);
1028 }
1029
1030 # Schedule a MTCR instruction that moves an integer register into the CR
1031 void::model-function::ppc_insn_mtcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rT, unsigned FXM
1032 if (!WITH_MODEL_ISSUE)
1033 return;
1034
1035 else {
1036 registers *cpu_regs = cpu_registers(processor);
1037 const unsigned ppc_RT = (rT - &cpu_regs->gpr[0]);
1038 const unsigned32 int_mask = (1 << ppc_RT);
1039 const unsigned32 cr_mask = 0xff;
1040 const model_time *normal_time = &model_ptr->timing[index];
1041 static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 };
1042 model_busy *busy_ptr;
1043 int i;
1044
1045 while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
1046 if (WITH_TRACE && ppc_trace[trace_model])
1047 model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
1048
1049 model_ptr->nr_stalls_data++;
1050 model_new_cycle(model_ptr);
1051 }
1052
1053 /* If only one bit is being moved, use the SCIU, not the MCIU on the 604 */
1054 if (CURRENT_MODEL == MODEL_ppc604 && (FXM & (FXM-1)) == 0) {
1055 normal_time = &ppc604_1bit_time;
1056 }
1057
1058 busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
1059 for (i = 0; i < 8; i++) {
1060 model_make_cr_reg_busy(model_ptr, busy_ptr, i);
1061 }
1062 }
1063
1064 # Convert a BIT32(x) number back into the original number
1065 int::model-internal::ppc_undo_bit32:unsigned bitmask
1066 unsigned u = 0x80000000;
1067 int i = 0;
1068 while (u && (u & bitmask) == 0) {
1069 u >>= 1;
1070 i++;
1071 }
1072
1073 return i;
1074
1075 # Schedule an instruction that takes 2 CR input registers and produces an output CR register
1076 void::model-function::ppc_insn_cr2:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned crA_bit, unsigned crB_bit
1077 if (!WITH_MODEL_ISSUE)
1078 return;
1079
1080 else {
1081 const unsigned ppc_CRA = ppc_undo_bit32(crA_bit);
1082 const unsigned ppc_CRB = ppc_undo_bit32(crB_bit);
1083 const unsigned32 cr_mask = (1 << ppc_CRA) | (1 << ppc_CRB) | (1 << crD);
1084 model_busy *busy_ptr;
1085
1086 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
1087 if (WITH_TRACE && ppc_trace[trace_model])
1088 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
1089
1090 model_ptr->nr_stalls_data++;
1091 model_new_cycle(model_ptr);
1092 }
1093
1094 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1095 model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
1096 }
1097
1098 # Schedule an instruction that takes 1 CR input registers and produces an output CR register
1099 void::model-function::ppc_insn_cr1:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned CRA
1100 if (!WITH_MODEL_ISSUE)
1101 return;
1102
1103 else {
1104 const unsigned32 cr_mask = (1 << CRA) | (1 << crD);
1105 model_busy *busy_ptr;
1106
1107 while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
1108 if (WITH_TRACE && ppc_trace[trace_model])
1109 model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
1110
1111 model_ptr->nr_stalls_data++;
1112 model_new_cycle(model_ptr);
1113 }
1114
1115 busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
1116 model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
1117 }
1118
1119 model_data *::model-function::model_create:cpu *processor
1120 model_data *model_ptr = ZALLOC(model_data);
1121 ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
1122 model_ptr->name = model_name[CURRENT_MODEL];
1123 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
1124 model_ptr->processor = processor;
1125 model_ptr->nr_cycles = 1;
1126 return model_ptr;
1127
1128 void::model-function::model_init:model_data *model_ptr
1129
1130 void::model-function::model_halt:model_data *model_ptr
1131 /* Let pipeline drain */
1132 while (model_ptr->busy_list)
1133 model_new_cycle(model_ptr);
1134
1135 model_print *::model-function::model_mon_info:model_data *model_ptr
1136 model_print *head;
1137 model_print *tail;
1138 ppc_function_unit i;
1139 count_type nr_insns;
1140 int j;
1141
1142 head = tail = ZALLOC(model_print);
1143 tail->count = model_ptr->nr_cycles;
1144 tail->name = "cycle";
1145 tail->suffix_plural = "s";
1146 tail->suffix_singular = "";
1147
1148 if (model_ptr->nr_stalls_data) {
1149 tail->next = ZALLOC(model_print);
1150 tail = tail->next;
1151 tail->count = model_ptr->nr_stalls_data;
1152 tail->name = "stall";
1153 tail->suffix_plural = "s waiting for data";
1154 tail->suffix_singular = " waiting for data";
1155 }
1156
1157 if (model_ptr->nr_stalls_unit) {
1158 tail->next = ZALLOC(model_print);
1159 tail = tail->next;
1160 tail->count = model_ptr->nr_stalls_unit;
1161 tail->name = "stall";
1162 tail->suffix_plural = "s waiting for a function unit";
1163 tail->suffix_singular = " waiting for a function unit";
1164 }
1165
1166 if (model_ptr->nr_stalls_serialize) {
1167 tail->next = ZALLOC(model_print);
1168 tail = tail->next;
1169 tail->count = model_ptr->nr_stalls_serialize;
1170 tail->name = "stall";
1171 tail->suffix_plural = "s waiting for serialization";
1172 tail->suffix_singular = " waiting for serialization";
1173 }
1174
1175 if (model_ptr->nr_branches) {
1176 tail->next = ZALLOC(model_print);
1177 tail = tail->next;
1178 tail->count = model_ptr->nr_branches;
1179 tail->name = "branch";
1180 tail->suffix_plural = "es";
1181 tail->suffix_singular = "";
1182 }
1183
1184 if (model_ptr->nr_branches_fallthrough) {
1185 tail->next = ZALLOC(model_print);
1186 tail = tail->next;
1187 tail->count = model_ptr->nr_branches_fallthrough;
1188 tail->name = "conditional branch";
1189 tail->suffix_plural = "es fell through";
1190 tail->suffix_singular = " fell through";
1191 }
1192
1193 if (model_ptr->nr_branch_predict_trues) {
1194 tail->next = ZALLOC(model_print);
1195 tail = tail->next;
1196 tail->count = model_ptr->nr_branch_predict_trues;
1197 tail->name = "successful branch prediction";
1198 tail->suffix_plural = "s";
1199 tail->suffix_singular = "";
1200 }
1201
1202 if (model_ptr->nr_branch_predict_falses) {
1203 tail->next = ZALLOC(model_print);
1204 tail = tail->next;
1205 tail->count = model_ptr->nr_branch_predict_falses;
1206 tail->name = "unsuccessful branch prediction";
1207 tail->suffix_plural = "s";
1208 tail->suffix_singular = "";
1209 }
1210
1211 for (j = 0; j < (sizeof(ppc_branch_conditional_name) / sizeof(ppc_branch_conditional_name[0])) ; j++) {
1212 if (model_ptr->nr_branch_conditional[j]) {
1213 tail->next = ZALLOC(model_print);
1214 tail = tail->next;
1215 tail->count = model_ptr->nr_branch_conditional[j];
1216 tail->name = ppc_branch_conditional_name[j];
1217 tail->suffix_plural = " conditional branches";
1218 tail->suffix_singular = " conditional branch";
1219 }
1220 }
1221
1222 nr_insns = 0;
1223 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
1224 if (model_ptr->nr_units[i]) {
1225 nr_insns += model_ptr->nr_units[i];
1226 tail->next = ZALLOC(model_print);
1227 tail = tail->next;
1228 tail->count = model_ptr->nr_units[i];
1229 tail->name = ppc_function_unit_name[i];
1230 tail->suffix_plural = "s";
1231 tail->suffix_singular = "";
1232 }
1233 }
1234
1235 tail->next = ZALLOC(model_print);
1236 tail = tail->next;
1237 tail->count = nr_insns;
1238 tail->name = "instruction";
1239 tail->suffix_plural = "s that were accounted for in timing info";
1240 tail->suffix_singular = " that was accounted for in timing info";
1241
1242 tail->next = (model_print *)0;
1243 return head;
1244
1245 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
1246 while (ptr) {
1247 model_print *next = ptr->next;
1248 free((void *)ptr);
1249 ptr = next;
1250 }
1251
1252 void::model-function::model_branches:model_data *model_ptr, int failed, int conditional
1253 model_ptr->nr_units[PPC_UNIT_BPU]++;
1254 if (failed)
1255 model_ptr->nr_branches_fallthrough++;
1256 else
1257 model_ptr->nr_branches++;
1258 if (conditional >= 0)
1259 model_ptr->nr_branch_conditional[conditional]++;
1260 model_new_cycle(model_ptr); /* A branch always ends the current cycle */
1261
1262 void::model-function::model_branch_predict:model_data *model_ptr, int success
1263 if (success)
1264 model_ptr->nr_branch_predict_trues++;
1265 else
1266 model_ptr->nr_branch_predict_falses++;
1267
1268 \f
1269 # The following (illegal) instruction is `known' by gen and is
1270 # called when ever an illegal instruction is encountered
1271 ::internal::illegal
1272 program_interrupt(processor, cia,
1273 illegal_instruction_program_interrupt);
1274 return 0;
1275
1276
1277 # The following (floating point unavailable) instruction is `known' by gen
1278 # and is called when ever an a floating point instruction is to be
1279 # executed but floating point is make unavailable by the MSR
1280 ::internal::floating_point_unavailable
1281 floating_point_unavailable_interrupt(processor, cia);
1282 return 0;
1283
1284
1285 #
1286 # Floating point support functions
1287 #
1288
1289 # Convert 32bit single to 64bit double
1290 unsigned64::function::DOUBLE:unsigned32 WORD
1291 unsigned64 FRT;
1292 if (EXTRACTED32(WORD, 1, 8) > 0
1293 && EXTRACTED32(WORD, 1, 8) < 255) {
1294 /* normalized operand */
1295 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
1296 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
1297 | INSERTED64(not_word_1_1, 2, 2)
1298 | INSERTED64(not_word_1_1, 3, 3)
1299 | INSERTED64(not_word_1_1, 4, 4)
1300 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
1301 }
1302 else if (EXTRACTED32(WORD, 1, 8) == 0
1303 && EXTRACTED32(WORD, 9, 31) != 0) {
1304 /* denormalized operand */
1305 int sign = EXTRACTED32(WORD, 0, 0);
1306 int exp = -126;
1307 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
1308 /* normalize the operand */
1309 while (MASKED64(frac, 0, 0) == 0) {
1310 frac <<= 1;
1311 exp -= 1;
1312 }
1313 FRT = (INSERTED64(sign, 0, 0)
1314 | INSERTED64(exp + 1023, 1, 11)
1315 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
1316 }
1317 else if (EXTRACTED32(WORD, 1, 8) == 255
1318 || EXTRACTED32(WORD, 1, 31) == 0) {
1319 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
1320 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
1321 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
1322 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
1323 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
1324 }
1325 else {
1326 error("DOUBLE - unknown case\n");
1327 FRT = 0;
1328 }
1329 return FRT;
1330
1331 # Convert 64bit single to 32bit double
1332 unsigned32::function::SINGLE:unsigned64 FRS
1333 unsigned32 WORD;
1334 if (EXTRACTED64(FRS, 1, 11) > 896
1335 || EXTRACTED64(FRS, 1, 63) == 0) {
1336 /* no denormalization required (includes Zero/Infinity/NaN) */
1337 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
1338 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
1339 }
1340 else if (874 <= EXTRACTED64(FRS, 1, 11)
1341 && EXTRACTED64(FRS, 1, 11) <= 896) {
1342 /* denormalization required */
1343 int sign = EXTRACTED64(FRS, 0, 0);
1344 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
1345 unsigned64 frac = (BIT64(0)
1346 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
1347 /* denormalize the operand */
1348 while (exp < -126) {
1349 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1350 exp += 1;
1351 }
1352 WORD = (INSERTED32(sign, 0, 0)
1353 | INSERTED32(0x00, 1, 8)
1354 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
1355 }
1356 else {
1357 WORD = 0x0; /* ??? */
1358 }
1359 return WORD;
1360
1361
1362 # round 64bit double to 64bit but single
1363 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
1364 /* comparisons ignore u bits */
1365 unsigned64 out;
1366 int inc = 0;
1367 int lsb = EXTRACTED64(*frac_grx, 23, 23);
1368 int gbit = EXTRACTED64(*frac_grx, 24, 24);
1369 int rbit = EXTRACTED64(*frac_grx, 25, 25);
1370 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
1371 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
1372 if (lsb == 1 && gbit == 1) inc = 1;
1373 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1374 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1375 }
1376 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
1377 if (sign == 0 && gbit == 1) inc = 1;
1378 if (sign == 0 && rbit == 1) inc = 1;
1379 if (sign == 0 && xbit == 1) inc = 1;
1380 }
1381 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
1382 if (sign == 1 && gbit == 1) inc = 1;
1383 if (sign == 1 && rbit == 1) inc = 1;
1384 if (sign == 1 && xbit == 1) inc = 1;
1385 }
1386 /* work out addition in low 25 bits of out */
1387 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
1388 *frac_grx = INSERTED64(out, 0, 23);
1389 if (out & BIT64(64 - 23 - 1 - 1)) {
1390 *frac_grx = (BIT64(0) |
1391 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
1392 *exp = *exp + 1;
1393 }
1394 /* frac_grx[24:52] = 0 already */
1395 FPSCR_SET_FR(inc);
1396 FPSCR_SET_FI(gbit || rbit || xbit);
1397
1398
1399 #
1400 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
1401 int inc = 0;
1402 if (round_mode == fpscr_rn_round_to_nearest) {
1403 if (*frac64 == 1 && gbit == 1) inc = 1;
1404 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
1405 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
1406 }
1407 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1408 if (sign == 0 && gbit == 1) inc = 1;
1409 if (sign == 0 && rbit == 1) inc = 1;
1410 if (sign == 0 && xbit == 1) inc = 1;
1411 }
1412 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1413 if (sign == 1 && gbit == 1) inc = 1;
1414 if (sign == 1 && rbit == 1) inc = 1;
1415 if (sign == 1 && xbit == 1) inc = 1;
1416 }
1417 /* frac[0:64] = frac[0:64} + inc */
1418 *frac += (*frac64 && inc ? 1 : 0);
1419 *frac64 = (*frac64 + inc) & 0x1;
1420 FPSCR_SET_FR(inc);
1421 FPSCR_SET_FI(gbit | rbit | xbit);
1422
1423
1424 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
1425 int carry_out;
1426 int inc = 0;
1427 int lsb = EXTRACTED64(*frac, 52, 52);
1428 int gbit = EXTRACTED64(*frac, 53, 53);
1429 int rbit = EXTRACTED64(*frac, 54, 54);
1430 int xbit = EXTRACTED64(*frac, 55, 55);
1431 if (round_mode == fpscr_rn_round_to_nearest) {
1432 if (lsb == 1 && gbit == 1) inc = 1;
1433 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
1434 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
1435 }
1436 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
1437 if (sign == 0 && gbit == 1) inc = 1;
1438 if (sign == 0 && rbit == 1) inc = 1;
1439 if (sign == 0 && xbit == 1) inc = 1;
1440 }
1441 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
1442 if (sign == 1 && gbit == 1) inc = 1;
1443 if (sign == 1 && rbit == 1) inc = 1;
1444 if (sign == 1 && xbit == 1) inc = 1;
1445 }
1446 /* frac//carry_out = frac + inc */
1447 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
1448 carry_out = EXTRACTED64(*frac, 0, 0);
1449 *frac <<= 1;
1450 if (carry_out == 1) *exp = *exp + 1;
1451 FPSCR_SET_FR(inc);
1452 FPSCR_SET_FI(gbit | rbit | xbit);
1453 FPSCR_SET_XX(FPSCR & fpscr_fi);
1454
1455
1456 # conversion of FP to integer
1457 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
1458 int i;
1459 int exp = 0;
1460 unsigned64 frac = 0;
1461 int frac64 = 0;
1462 int gbit = 0;
1463 int rbit = 0;
1464 int xbit = 0;
1465 int sign = EXTRACTED64(frb, 0, 0);
1466 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1467 goto Infinity_Operand;
1468 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1469 goto SNaN_Operand;
1470 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1471 goto QNaN_Operand;
1472 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
1473 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1474 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1475 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1476 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1477 frac64 = 0;
1478 }
1479 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1480 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1481 frac64 = 0;
1482 }
1483 gbit = 0, rbit = 0, xbit = 0;
1484 for (i = 1; i <= 63 - exp; i++) {
1485 xbit = rbit | xbit;
1486 rbit = gbit;
1487 gbit = frac64;
1488 frac64 = EXTRACTED64(frac, 63, 63);
1489 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1490 }
1491 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1492 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1493 frac = ~frac;
1494 frac64 ^= 1;
1495 frac += (frac64 ? 1 : 0);
1496 frac64 = (frac64 + 1) & 0x1;
1497 }
1498 if (tgt_precision == 32 /* can ignore frac64 in compare */
1499 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1500 goto Large_Operand;
1501 if (tgt_precision == 64 /* can ignore frac64 in compare */
1502 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1503 goto Large_Operand;
1504 if (tgt_precision == 32 /* can ignore frac64 in compare */
1505 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1506 goto Large_Operand;
1507 if (tgt_precision == 64 /* can ignore frac64 in compare */
1508 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1509 goto Large_Operand;
1510 FPSCR_SET_XX(FPSCR & fpscr_fi);
1511 if (tgt_precision == 32)
1512 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1513 if (tgt_precision == 64)
1514 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1515 /*FPSCR[fprf] = undefined */
1516 goto Done;
1517 /**/
1518 Infinity_Operand:
1519 FPSCR_SET_FR(0);
1520 FPSCR_SET_FI(0);
1521 FPSCR_OR_VX(fpscr_vxcvi);
1522 if ((FPSCR & fpscr_ve) == 0) {
1523 if (tgt_precision == 32) {
1524 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1525 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1526 }
1527 else {
1528 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1529 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1530 }
1531 /* FPSCR[FPRF] = undefined */
1532 }
1533 goto Done;
1534 /**/
1535 SNaN_Operand:
1536 FPSCR_SET_FR(0);
1537 FPSCR_SET_FI(0);
1538 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1539 if ((FPSCR & fpscr_ve) == 0) {
1540 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1541 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1542 /* FPSCR[fprf] = undefined */
1543 }
1544 goto Done;
1545 /**/
1546 QNaN_Operand:
1547 FPSCR_SET_FR(0);
1548 FPSCR_SET_FI(0);
1549 FPSCR_OR_VX(fpscr_vxcvi);
1550 if ((FPSCR & fpscr_ve) == 0) {
1551 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1552 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1553 /* FPSCR[fprf] = undefined */
1554 }
1555 goto Done;
1556 /**/
1557 Large_Operand:
1558 FPSCR_SET_FR(0);
1559 FPSCR_SET_FI(0);
1560 FPSCR_OR_VX(fpscr_vxcvi);
1561 if ((FPSCR & fpscr_ve) == 0) {
1562 if (tgt_precision == 32) {
1563 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1564 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1565 }
1566 else {
1567 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1568 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1569 }
1570 /* FPSCR[fprf] = undefined */
1571 }
1572 /**/
1573 Done:
1574
1575
1576 # extract out raw fields of a FP number
1577 int::function::sign:unsigned64 FRS
1578 return (MASKED64(FRS, 0, 0)
1579 ? -1
1580 : 1);
1581 int::function::biased_exp:unsigned64 frs, int single
1582 if (single)
1583 return EXTRACTED64(frs, 1, 8);
1584 else
1585 return EXTRACTED64(frs, 1, 11);
1586 unsigned64::function::fraction:unsigned64 frs, int single
1587 if (single)
1588 return EXTRACTED64(frs, 9, 31);
1589 else
1590 return EXTRACTED64(frs, 12, 63);
1591
1592 # a number?, each of the below return +1 or -1 (based on sign bit)
1593 # if true.
1594 int::function::is_nor:unsigned64 frs, int single
1595 int exp = biased_exp(frs, single);
1596 return (exp >= 1
1597 && exp <= (single ? 254 : 2046));
1598 int::function::is_zero:unsigned64 FRS
1599 return (MASKED64(FRS, 1, 63) == 0
1600 ? sign(FRS)
1601 : 0);
1602 int::function::is_den:unsigned64 frs, int single
1603 int exp = biased_exp(frs, single);
1604 unsigned64 frac = fraction(frs, single);
1605 return (exp == 0 && frac != 0
1606 ? sign(frs)
1607 : 0);
1608 int::function::is_inf:unsigned64 frs, int single
1609 int exp = biased_exp(frs, single);
1610 int frac = fraction(frs, single);
1611 return (exp == (single ? 255 : 2047) && frac == 0
1612 ? sign(frs)
1613 : 0);
1614 int::function::is_NaN:unsigned64 frs, int single
1615 int exp = biased_exp(frs, single);
1616 int frac = fraction(frs, single);
1617 return (exp == (single ? 255 : 2047) && frac != 0
1618 ? sign(frs)
1619 : 0);
1620 int::function::is_SNaN:unsigned64 frs, int single
1621 return (is_NaN(frs, single)
1622 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1623 ? sign(frs)
1624 : 0);
1625 int::function::is_QNaN:unsigned64 frs, int single
1626 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1627 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1628 return *(double*)fra < *(double*)frb;
1629 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1630 return *(double*)fra > *(double*)frb;
1631 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1632 return *(double*)fra == *(double*)frb;
1633
1634
1635 # which quiet nan should become the result
1636 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1637 unsigned64 frt = 0;
1638 if (is_NaN(fra, single))
1639 frt = fra;
1640 else if (is_NaN(frb, single))
1641 if (instruction_is_frsp)
1642 frt = MASKED64(frb, 0, 34);
1643 else
1644 frt = frb;
1645 else if (is_NaN(frc, single))
1646 frt = frc;
1647 else if (generate_qnan)
1648 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1649 else
1650 error("select_qnan - default reached\n");
1651 return frt;
1652
1653
1654 # detect invalid operation
1655 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1656 int fail = 0;
1657 if ((check & fpscr_vxsnan)
1658 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1659 FPSCR_OR_VX(fpscr_vxsnan);
1660 fail = 1;
1661 }
1662 if ((check & fpscr_vxisi)
1663 && (is_inf(fra, single) && is_inf(frb, single))
1664 && ((negate && sign(fra) != sign(frb))
1665 || (!negate && sign(fra) == sign(frb)))) {
1666 /*FIXME: don't handle inf-inf VS inf+-inf */
1667 FPSCR_OR_VX(fpscr_vxisi);
1668 fail = 1;
1669 }
1670 if ((check & fpscr_vxidi)
1671 && (is_inf(fra, single) && is_inf(frb, single))) {
1672 FPSCR_OR_VX(fpscr_vxidi);
1673 fail = 1;
1674 }
1675 if ((check & fpscr_vxzdz)
1676 && (is_zero(fra) && is_zero(frb))) {
1677 FPSCR_OR_VX(fpscr_vxzdz);
1678 fail = 1;
1679 }
1680 if ((check & fpscr_vximz)
1681 && (is_zero(fra) && is_inf(frb, single))) {
1682 FPSCR_OR_VX(fpscr_vximz);
1683 fail = 1;
1684 }
1685 if ((check & fpscr_vxvc)
1686 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1687 FPSCR_OR_VX(fpscr_vxvc);
1688 fail = 1;
1689 }
1690 if ((check & fpscr_vxsoft)) {
1691 FPSCR_OR_VX(fpscr_vxsoft);
1692 fail = 1;
1693 }
1694 if ((check & fpscr_vxsqrt)
1695 && sign(fra) < 0) {
1696 FPSCR_OR_VX(fpscr_vxsqrt);
1697 fail = 1;
1698 }
1699 /* if ((check && fpscr_vxcvi) {
1700 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1701 FPSCR_OR_VX(fpscr_vxcvi);
1702 fail = 1;
1703 }
1704 */
1705 return fail;
1706
1707
1708
1709
1710
1711 # handle case of invalid operation
1712 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
1713 if (FPSCR & fpscr_ve) {
1714 /* invalid operation exception enabled */
1715 /* FRT unchaged */
1716 FPSCR_SET_FR(0);
1717 FPSCR_SET_FI(0);
1718 /* fpscr_FPRF unchanged */
1719 }
1720 else {
1721 /* invalid operation exception disabled */
1722 if (instruction_is_convert_to_64bit) {
1723 error("oopsi");
1724 }
1725 else if (instruction_is_convert_to_32bit) {
1726 error("oopsi");
1727 }
1728 else { /* arrith, frsp */
1729 *frt = select_qnan(fra, frb, frc,
1730 instruction_is_frsp, 0/*generate*/, single);
1731 FPSCR_SET_FR(0);
1732 FPSCR_SET_FI(0);
1733 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1734 }
1735 }
1736
1737
1738
1739
1740 #
1741 # I.2.4.1 Branch Instructions
1742 #
1743 0.18,6.LI,30.AA,31.LK:I:t::Branch
1744 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1745 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1746 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1747 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1748 if (AA) NIA = IEA(EXTS(LI_0b00));
1749 else NIA = IEA(CIA + EXTS(LI_0b00));
1750 if (LK) LR = (spreg)CIA+4;
1751 model_branches(cpu_model(processor), 1, -1);
1752
1753 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
1754 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1755 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1756 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1757 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1758 int M, ctr_ok, cond_ok, succeed;
1759 if (! BO{0})
1760 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1761 if (is_64bit_implementation && is_64bit_mode) M = 0;
1762 else M = 32;
1763 if (!BO{2}) CTR = CTR - 1;
1764 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1765 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1766 if (ctr_ok && cond_ok) {
1767 if (AA) NIA = IEA(EXTS(BD_0b00));
1768 else NIA = IEA(CIA + EXTS(BD_0b00));
1769 succeed = 1;
1770 }
1771 else
1772 succeed = 0;
1773 if (LK) LR = (spreg)IEA(CIA + 4);
1774 model_branches(cpu_model(processor), succeed, BO);
1775 if (! BO{0}) {
1776 int reverse;
1777 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1778 reverse = EXTS(BD_0b00) < 0;
1779 } else { /* branch prediction bit not set */
1780 reverse = EXTS(BD_0b00) >= 0;
1781 }
1782 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1783 }
1784
1785 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
1786 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1787 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1788 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1789 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1790 int M, ctr_ok, cond_ok, succeed;
1791 if (is_64bit_implementation && is_64bit_mode) M = 0;
1792 else M = 32;
1793 if (! BO{0})
1794 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1795 if (!BO{2}) CTR = CTR - 1;
1796 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1797 cond_ok = BO{0} || (CR{BI} == BO{1});
1798 if (ctr_ok && cond_ok) {
1799 NIA = IEA(LR_0b00);
1800 succeed = 1;
1801 }
1802 else
1803 succeed = 0;
1804 if (LK) LR = (spreg)IEA(CIA + 4);
1805 model_branches(cpu_model(processor), succeed, BO);
1806 if (! BO{0})
1807 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1808
1809 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
1810 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1811 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1812 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1813 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1814 int cond_ok, succeed;
1815 if (! BO{0})
1816 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1817 cond_ok = BO{0} || (CR{BI} == BO{1});
1818 if (cond_ok) {
1819 NIA = IEA(CTR_0b00);
1820 succeed = 1;
1821 }
1822 else
1823 succeed = 0;
1824 if (LK) LR = (spreg)IEA(CIA + 4);
1825 model_branches(cpu_model(processor), succeed, BO);
1826 if (! BO{0})
1827 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1828
1829 #
1830 # I.2.4.2 System Call Instruction
1831 #
1832 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
1833 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1834 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1835 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1836 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1837 model_serialize(my_index, cpu_model(processor));
1838 system_call_interrupt(processor, cia);
1839
1840 #
1841 # I.2.4.3 Condition Register Logical Instructions
1842 #
1843 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1844 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1845 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1846 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1847 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1848 BLIT32(CR, BT, CR{BA} && CR{BB});
1849 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1850
1851 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
1852 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1853 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1854 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1855 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1856 BLIT32(CR, BT, CR{BA} || CR{BB});
1857 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1858
1859 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
1860 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1861 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1862 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1863 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1864 BLIT32(CR, BT, CR{BA} != CR{BB});
1865 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1866
1867 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
1868 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1869 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1870 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1871 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1872 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
1873 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1874
1875 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
1876 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1877 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1878 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1879 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1880 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
1881 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1882
1883 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
1884 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1885 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1886 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1887 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1888 BLIT32(CR, BT, CR{BA} == CR{BB});
1889 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1890
1891 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
1892 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1893 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1894 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1895 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1896 BLIT32(CR, BT, CR{BA} && !CR{BB});
1897 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1898
1899 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
1900 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1901 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1902 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1903 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1904 BLIT32(CR, BT, CR{BA} || !CR{BB});
1905 ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
1906
1907 #
1908 # I.2.4.4 Condition Register Field Instruction
1909 #
1910 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1911 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1912 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1913 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1914 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1915 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1916 ppc_insn_cr1(my_index, processor, cpu_model(processor), BF, BFA);
1917
1918
1919 #
1920 # I.3.3.2 Fixed-Point Load Instructions
1921 #
1922
1923 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1924 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1925 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1926 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1927 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1928 unsigned_word b;
1929 unsigned_word EA;
1930 if (RA == 0) b = 0;
1931 else b = *rA;
1932 EA = b + EXTS(D);
1933 *rT = MEM(unsigned, EA, 1);
1934 if (RA == 0)
1935 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1936 else
1937 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
1938
1939
1940 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1941 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1942 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1943 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1944 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1945 unsigned_word b;
1946 unsigned_word EA;
1947 if (RA == 0) b = 0;
1948 else b = *rA;
1949 EA = b + *rB;
1950 *rT = MEM(unsigned, EA, 1);
1951 if (RA == 0)
1952 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
1953 else
1954 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
1955
1956 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1957 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1958 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1959 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1960 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1961 unsigned_word EA;
1962 if (RA == 0 || RA == RT)
1963 program_interrupt(processor, cia,
1964 illegal_instruction_program_interrupt);
1965 EA = *rA + EXTS(D);
1966 *rT = MEM(unsigned, EA, 1);
1967 *rA = EA;
1968 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
1969
1970 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1971 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1972 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1973 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1974 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1975 unsigned_word EA;
1976 if (RA == 0 || RA == RT)
1977 program_interrupt(processor, cia,
1978 illegal_instruction_program_interrupt);
1979 EA = *rA + *rB;
1980 *rT = MEM(unsigned, EA, 1);
1981 *rA = EA;
1982 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
1983
1984 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1985 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1986 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1987 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1988 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1989 unsigned_word b;
1990 unsigned_word EA;
1991 if (RA == 0) b = 0;
1992 else b = *rA;
1993 EA = b + EXTS(D);
1994 *rT = MEM(unsigned, EA, 2);
1995 if (RA == 0)
1996 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
1997 else
1998 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
1999
2000 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
2001 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2002 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2003 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2004 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2005 unsigned_word b;
2006 unsigned_word EA;
2007 if (RA == 0) b = 0;
2008 else b = *rA;
2009 EA = b + *rB;
2010 *rT = MEM(unsigned, EA, 2);
2011 if (RA == 0)
2012 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2013 else
2014 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2015
2016 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
2017 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2018 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2019 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2020 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2021 unsigned_word EA;
2022 if (RA == 0 || RA == RT)
2023 program_interrupt(processor, cia,
2024 illegal_instruction_program_interrupt);
2025 EA = *rA + EXTS(D);
2026 *rT = MEM(unsigned, EA, 2);
2027 *rA = EA;
2028 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
2029
2030 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
2031 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2032 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2033 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2034 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2035 unsigned_word EA;
2036 if (RA == 0 || RA == RT)
2037 program_interrupt(processor, cia,
2038 illegal_instruction_program_interrupt);
2039 EA = *rA + *rB;
2040 *rT = MEM(unsigned, EA, 2);
2041 *rA = EA;
2042 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
2043
2044 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
2045 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2046 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2047 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2048 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2049 unsigned_word b;
2050 unsigned_word EA;
2051 if (RA == 0) b = 0;
2052 else b = *rA;
2053 EA = b + EXTS(D);
2054 *rT = MEM(signed, EA, 2);
2055 if (RA == 0)
2056 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2057 else
2058 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2059
2060 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
2061 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2062 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2063 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2064 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2065 unsigned_word b;
2066 unsigned_word EA;
2067 if (RA == 0) b = 0;
2068 else b = *rA;
2069 EA = b + *rB;
2070 *rT = MEM(signed, EA, 2);
2071 if (RA == 0)
2072 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2073 else
2074 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2075
2076 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
2077 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2078 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2079 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2080 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2081 unsigned_word EA;
2082 if (RA == 0 || RA == RT)
2083 program_interrupt(processor, cia,
2084 illegal_instruction_program_interrupt);
2085 EA = *rA + EXTS(D);
2086 *rT = MEM(signed, EA, 2);
2087 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
2088
2089 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
2090 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2091 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2092 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2093 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2094 unsigned_word EA;
2095 if (RA == 0 || RA == RT)
2096 program_interrupt(processor, cia,
2097 illegal_instruction_program_interrupt);
2098 EA = *rA + *rB;
2099 *rT = MEM(signed, EA, 2);
2100 *rA = EA;
2101 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
2102
2103 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
2104 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2105 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2106 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2107 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2108 unsigned_word b;
2109 unsigned_word EA;
2110 if (RA == 0) b = 0;
2111 else b = *rA;
2112 EA = b + EXTS(D);
2113 *rT = MEM(unsigned, EA, 4);
2114 if (RA == 0)
2115 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2116 else
2117 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2118
2119 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
2120 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2121 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2122 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2123 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2124 unsigned_word b;
2125 unsigned_word EA;
2126 if (RA == 0) b = 0;
2127 else b = *rA;
2128 EA = b + *rB;
2129 *rT = MEM(unsigned, EA, 4);
2130 if (RA == 0)
2131 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2132 else
2133 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2134
2135 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
2136 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2137 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2138 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2139 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2140 unsigned_word EA;
2141 if (RA == 0 || RA == RT)
2142 program_interrupt(processor, cia,
2143 illegal_instruction_program_interrupt);
2144 EA = *rA + EXTS(D);
2145 *rT = MEM(unsigned, EA, 4);
2146 *rA = EA;
2147 ppc_insn_int1_update(my_index, processor, cpu_model(processor), rT, rA);
2148
2149 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
2150 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
2151 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2152 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2153 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2154 unsigned_word EA;
2155 if (RA == 0 || RA == RT)
2156 program_interrupt(processor, cia,
2157 illegal_instruction_program_interrupt);
2158 EA = *rA + *rB;
2159 *rT = MEM(unsigned, EA, 4);
2160 *rA = EA;
2161 ppc_insn_int2_update(my_index, processor, cpu_model(processor), rT, rA, rB);
2162
2163 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
2164 # unsigned_word b;
2165 # unsigned_word EA;
2166 # if (RA == 0) b = 0;
2167 # else b = *rA;
2168 # EA = b + EXTS(DS_0b00);
2169 # *rT = MEM(signed, EA, 4);
2170
2171 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
2172 # unsigned_word b;
2173 # unsigned_word EA;
2174 # if (RA == 0) b = 0;
2175 # else b = *rA;
2176 # EA = b + *rB;;
2177 # *rT = MEM(signed, EA, 4);
2178
2179 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
2180 # unsigned_word EA;
2181 # if (RA == 0 || RA == RT)
2182 # program_interrupt(processor, cia
2183 # illegal_instruction_program_interrupt);
2184 # EA = *rA + *rB;
2185 # *rT = MEM(signed, EA, 4);
2186 # *rA = EA;
2187
2188 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
2189 # unsigned_word b;
2190 # unsigned_word EA;
2191 # if (RA == 0) b = 0;
2192 # else b = *rA;
2193 # EA = b + EXTS(DS_0b00);
2194 # *rT = MEM(unsigned, EA, 8);
2195
2196 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
2197 # unsigned_word b;
2198 # unsigned_word EA;
2199 # if (RA == 0) b = 0;
2200 # else b = *rA;
2201 # EA = b + *rB;
2202 # *rT = MEM(unsigned, EA, 8);
2203
2204 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
2205 # unsigned_word EA;
2206 # if (RA == 0 || RA == RT)
2207 # program_interrupt(processor, cia
2208 # illegal_instruction_program_interrupt);
2209 # EA = *rA + EXTS(DS_0b00);
2210 # *rT = MEM(unsigned, EA, 8);
2211 # *rA = EA;
2212
2213 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
2214 # unsigned_word EA;
2215 # if (RA == 0 || RA == RT)
2216 # program_interrupt(processor, cia
2217 # illegal_instruction_program_interrupt);
2218 # EA = *rA + *rB;
2219 # *rT = MEM(unsigned, EA, 8);
2220 # *rA = EA;
2221
2222
2223
2224 #
2225 # I.3.3.3 Fixed-Point Store Instructions
2226 #
2227
2228 0.38,6.RS,11.RA,16.D:D:::Store Byte
2229 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2230 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2231 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2232 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2233 unsigned_word b;
2234 unsigned_word EA;
2235 if (RA == 0) b = 0;
2236 else b = *rA;
2237 EA = b + EXTS(D);
2238 STORE(EA, 1, *rS);
2239 if (RA == 0)
2240 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
2241 else
2242 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
2243
2244 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
2245 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2246 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2247 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2248 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2249 unsigned_word b;
2250 unsigned_word EA;
2251 if (RA == 0) b = 0;
2252 else b = *rA;
2253 EA = b + *rB;
2254 STORE(EA, 1, *rS);
2255 if (RA == 0)
2256 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2257 else
2258 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2259
2260 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
2261 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2262 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2263 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2264 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2265 unsigned_word EA;
2266 if (RA == 0)
2267 program_interrupt(processor, cia,
2268 illegal_instruction_program_interrupt);
2269 EA = *rA + EXTS(D);
2270 STORE(EA, 1, *rS);
2271 *rA = EA;
2272 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
2273
2274 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
2275 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2276 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2277 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2278 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2279 unsigned_word EA;
2280 if (RA == 0)
2281 program_interrupt(processor, cia,
2282 illegal_instruction_program_interrupt);
2283 EA = *rA + *rB;
2284 STORE(EA, 1, *rS);
2285 *rA = EA;
2286 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
2287
2288 0.44,6.RS,11.RA,16.D:D:::Store Half Word
2289 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2290 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2291 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2292 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2293 unsigned_word b;
2294 unsigned_word EA;
2295 if (RA == 0) b = 0;
2296 else b = *rA;
2297 EA = b + EXTS(D);
2298 STORE(EA, 2, *rS);
2299 if (RA == 0)
2300 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
2301 else
2302 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
2303
2304 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
2305 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2306 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2307 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2308 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2309 unsigned_word b;
2310 unsigned_word EA;
2311 if (RA == 0) b = 0;
2312 else b = *rA;
2313 EA = b + *rB;
2314 STORE(EA, 2, *rS);
2315 if (RA == 0)
2316 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2317 else
2318 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2319
2320 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
2321 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2322 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2323 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2324 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2325 unsigned_word EA;
2326 if (RA == 0)
2327 program_interrupt(processor, cia,
2328 illegal_instruction_program_interrupt);
2329 EA = *rA + EXTS(D);
2330 STORE(EA, 2, *rS);
2331 *rA = EA;
2332 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
2333
2334 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
2335 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2336 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2337 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2338 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2339 unsigned_word EA;
2340 if (RA == 0)
2341 program_interrupt(processor, cia,
2342 illegal_instruction_program_interrupt);
2343 EA = *rA + *rB;
2344 STORE(EA, 2, *rS);
2345 *rA = EA;
2346 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
2347
2348 0.36,6.RS,11.RA,16.D:D:::Store Word
2349 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2350 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2351 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2352 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2353 unsigned_word b;
2354 unsigned_word EA;
2355 if (RA == 0) b = 0;
2356 else b = *rA;
2357 EA = b + EXTS(D);
2358 STORE(EA, 4, *rS);
2359 if (RA == 0)
2360 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
2361 else
2362 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rA);
2363
2364 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
2365 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2366 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2367 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2368 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2369 unsigned_word b;
2370 unsigned_word EA;
2371 if (RA == 0) b = 0;
2372 else b = *rA;
2373 EA = b + *rB;
2374 STORE(EA, 4, *rS);
2375 if (RA == 0)
2376 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2377 else
2378 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2379
2380 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
2381 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2382 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2383 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2384 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2385 unsigned_word EA;
2386 if (RA == 0)
2387 program_interrupt(processor, cia,
2388 illegal_instruction_program_interrupt);
2389 EA = *rA + EXTS(D);
2390 STORE(EA, 4, *rS);
2391 *rA = EA;
2392 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rA, 0/*Rc*/);
2393
2394 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
2395 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2396 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2397 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2398 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2399 unsigned_word EA;
2400 if (RA == 0)
2401 program_interrupt(processor, cia,
2402 illegal_instruction_program_interrupt);
2403 EA = *rA + *rB;
2404 STORE(EA, 4, *rS);
2405 *rA = EA;
2406 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rA, rB, 0/*Rc*/);
2407
2408 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2409 # unsigned_word b;
2410 # unsigned_word EA;
2411 # if (RA == 0) b = 0;
2412 # else b = *rA;
2413 # EA = b + EXTS(DS_0b00);
2414 # STORE(EA, 8, *rS);
2415 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2416 # unsigned_word b;
2417 # unsigned_word EA;
2418 # if (RA == 0) b = 0;
2419 # else b = *rA;
2420 # EA = b + *rB;
2421 # STORE(EA, 8, *rS);
2422 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2423 # unsigned_word EA;
2424 # if (RA == 0)
2425 # program_interrupt(processor, cia
2426 # illegal_instruction_program_interrupt);
2427 # EA = *rA + EXTS(DS_0b00);
2428 # STORE(EA, 8, *rS);
2429 # *rA = EA;
2430 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2431 # unsigned_word EA;
2432 # if (RA == 0)
2433 # program_interrupt(processor, cia
2434 # illegal_instruction_program_interrupt);
2435 # EA = *rA + *rB;
2436 # STORE(EA, 8, *rS);
2437 # *rA = EA;
2438
2439
2440 #
2441 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2442 #
2443
2444 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2445 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2446 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2447 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2448 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2449 unsigned_word b;
2450 unsigned_word EA;
2451 if (RA == 0) b = 0;
2452 else b = *rA;
2453 EA = b + *rB;
2454 *rT = SWAP_2(MEM(unsigned, EA, 2));
2455 if (RA == 0)
2456 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2457 else
2458 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2459
2460 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2461 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2462 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2463 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2464 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2465 unsigned_word b;
2466 unsigned_word EA;
2467 if (RA == 0) b = 0;
2468 else b = *rA;
2469 EA = b + *rB;
2470 *rT = SWAP_4(MEM(unsigned, EA, 4));
2471 if (RA == 0)
2472 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rB, 0/*Rc*/);
2473 else
2474 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, 0/*Rc*/);
2475
2476 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2477 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2478 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2479 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2480 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2481 unsigned_word b;
2482 unsigned_word EA;
2483 if (RA == 0) b = 0;
2484 else b = *rA;
2485 EA = b + *rB;
2486 STORE(EA, 2, SWAP_2(*rS));
2487 if (RA == 0)
2488 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2489 else
2490 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2491
2492 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2493 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2494 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2495 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2496 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2497 unsigned_word b;
2498 unsigned_word EA;
2499 if (RA == 0) b = 0;
2500 else b = *rA;
2501 EA = b + *rB;
2502 STORE(EA, 4, SWAP_4(*rS));
2503 if (RA == 0)
2504 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
2505 else
2506 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
2507
2508
2509 #
2510 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2511 #
2512
2513 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
2514
2515 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2516
2517
2518 #
2519 # I.3.3.6 Fixed-Point Move Assist Instructions
2520 #
2521
2522 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
2523
2524 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2525
2526 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
2527
2528 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2529
2530
2531 #
2532 # I.3.3.7 Storage Synchronization Instructions
2533 #
2534 # HACK: Rather than monitor addresses looking for a reason
2535 # to cancel a reservation. This code instead keeps
2536 # a copy of the data read from memory. Before performing
2537 # a store, the memory area is checked to see if it has
2538 # been changed.
2539 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2540 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2541 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2542 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2543 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2544 unsigned_word b;
2545 unsigned_word EA;
2546 if (RA == 0) b = 0;
2547 else b = *rA;
2548 EA = b + *rB;
2549 RESERVE = 1;
2550 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2551 RESERVE_DATA = MEM(unsigned, EA, 4);
2552 *rT = RESERVE_DATA;
2553
2554 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2555 unsigned_word b;
2556 unsigned_word EA;
2557 if (RA == 0) b = 0;
2558 else b = *rA;
2559 EA = b + *rB;
2560 RESERVE = 1;
2561 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2562 RESERVE_DATA = MEM(unsigned, EA, 8);
2563 *rT = RESERVE_DATA;
2564
2565 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2566 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2567 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2568 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2569 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2570 unsigned_word b;
2571 unsigned_word EA;
2572 if (RA == 0) b = 0;
2573 else b = *rA;
2574 EA = b + *rB;
2575 if (RESERVE) {
2576 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2577 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2578 STORE(EA, 4, *rS);
2579 CR_SET_XER_SO(0, cr_i_zero);
2580 }
2581 else {
2582 /* ment to randomly to store, we never do! */
2583 CR_SET_XER_SO(0, 0);
2584 }
2585 RESERVE = 0;
2586 }
2587 else {
2588 CR_SET_XER_SO(0, 0);
2589 }
2590 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2591 unsigned_word b;
2592 unsigned_word EA;
2593 if (RA == 0) b = 0;
2594 else b = *rA;
2595 EA = b + *rB;
2596 if (RESERVE) {
2597 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2598 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2599 STORE(EA, 8, *rS);
2600 CR_SET_XER_SO(0, cr_i_zero);
2601 }
2602 else {
2603 /* ment to randomly to store, we never do */
2604 CR_SET_XER_SO(0, 0);
2605 }
2606 RESERVE = 0;
2607 }
2608 else {
2609 CR_SET_XER_SO(0, 0);
2610 }
2611
2612 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2613 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2614 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2615 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2616 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2617 /* do nothing */
2618
2619
2620 #
2621 # I.3.3.9 Fixed-Point Arithmetic Instructions
2622 #
2623
2624 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
2625 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2626 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2627 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2628 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2629 if (RA_is_0) {
2630 *rT = EXTS(SI);
2631 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2632 }
2633 else {
2634 *rT = *rA + EXTS(SI);
2635 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2636 }
2637
2638 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2639 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2640 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2641 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2642 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2643 if (RA_is_0) {
2644 *rT = EXTS(SI) << 16;
2645 ppc_insn_int0(my_index, processor, cpu_model(processor), rT, 0/*Rc*/);
2646 }
2647 else {
2648 *rT = *rA + (EXTS(SI) << 16);
2649 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2650 }
2651
2652 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2653 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2654 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2655 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2656 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2657 ALU_BEGIN(*rA);
2658 ALU_ADD(*rB);
2659 ALU_END(*rT, 0/*CA*/, OE, Rc);
2660 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2661
2662 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2663 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2664 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2665 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2666 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2667 ALU_BEGIN(*rA);
2668 ALU_NOT;
2669 ALU_ADD(*rB);
2670 ALU_ADD(1);
2671 ALU_END(*rT, 0/*CA*/, OE, Rc);
2672 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2673
2674 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2675 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2676 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2677 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2678 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2679 ALU_BEGIN(*rA);
2680 ALU_ADD(EXTS(SI));
2681 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2682 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2683
2684 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2685 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2686 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2687 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2688 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2689 ALU_BEGIN(*rA);
2690 ALU_ADD(EXTS(SI));
2691 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2692 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 1/*Rc*/);
2693
2694 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2695 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2696 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2697 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2698 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2699 ALU_BEGIN(*rA);
2700 ALU_NOT;
2701 ALU_ADD(EXTS(SI));
2702 ALU_ADD(1);
2703 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2704 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2705
2706 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2707 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2708 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2709 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2710 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2711 ALU_BEGIN(*rA);
2712 ALU_ADD(*rB);
2713 ALU_END(*rT, 1/*CA*/, OE, Rc);
2714 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2715
2716 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2717 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2718 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2719 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2720 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2721 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2722 ALU_BEGIN(*rA);
2723 ALU_NOT;
2724 ALU_ADD(*rB);
2725 ALU_ADD(1);
2726 ALU_END(*rT, 1/*CA*/, OE, Rc);
2727 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2728
2729 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2730 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2731 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2732 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2733 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2734 ALU_BEGIN(*rA);
2735 ALU_ADD(*rB);
2736 ALU_ADD_CA;
2737 ALU_END(*rT, 1/*CA*/, OE, Rc);
2738 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2739
2740 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2741 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2742 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2743 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2744 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2745 ALU_BEGIN(*rA);
2746 ALU_NOT;
2747 ALU_ADD(*rB);
2748 ALU_ADD_CA;
2749 ALU_END(*rT, 1/*CA*/, OE, Rc);
2750 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2751
2752 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2753 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2754 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2755 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2756 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2757 # ALU_BEGIN(*rA);
2758 # ALU_ADD_CA;
2759 # ALU_SUB(1);
2760 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2761
2762 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
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 # ALU_BEGIN(*rA);
2768 # ALU_NOT;
2769 # ALU_ADD_CA;
2770 # ALU_SUB(1);
2771 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2772
2773 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2774 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2775 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2776 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2777 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2778 ALU_BEGIN(*rA);
2779 ALU_ADD_CA;
2780 ALU_END(*rT, 1/*CA*/, OE, Rc);
2781 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2782
2783 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2784 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2785 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2786 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2787 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2788 ALU_BEGIN(*rA);
2789 ALU_NOT;
2790 ALU_ADD_CA;
2791 ALU_END(*rT, 1/*CA*/, OE, Rc);
2792 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2793
2794 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2795 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2796 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2797 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2798 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2799 ALU_BEGIN(*rA);
2800 ALU_NOT;
2801 ALU_ADD(1);
2802 ALU_END(*rT,0/*CA*/,OE,Rc);
2803 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, Rc);
2804
2805 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2806 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2807 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2808 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2809 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2810 signed_word prod = *rA * EXTS(SI);
2811 *rT = prod;
2812 ppc_insn_int1(my_index, processor, cpu_model(processor), rT, rA, 0/*Rc*/);
2813
2814 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2815
2816 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2817 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2818 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2819 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2820 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2821 signed64 a = (signed32)(*rA);
2822 signed64 b = (signed32)(*rB);
2823 signed64 prod = a * b;
2824 signed_word t = prod;
2825 *rT = *rA * *rB;
2826 if (t != prod && OE)
2827 XER |= (xer_overflow | xer_summary_overflow);
2828 CR0_COMPARE(t, 0, Rc);
2829 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2830
2831 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2832
2833 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2834 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2835 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2836 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2837 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2838 signed64 a = (signed32)(*rA);
2839 signed64 b = (signed32)(*rB);
2840 signed64 prod = a * b;
2841 signed_word t = EXTRACTED64(prod, 0, 31);
2842 *rT = t;
2843 CR0_COMPARE(t, 0, Rc);
2844 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2845
2846 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2847
2848 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2849 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2850 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2851 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2852 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2853 unsigned64 a = (unsigned32)(*rA);
2854 unsigned64 b = (unsigned32)(*rB);
2855 unsigned64 prod = a * b;
2856 signed_word t = EXTRACTED64(prod, 0, 31);
2857 *rT = t;
2858 CR0_COMPARE(t, 0, Rc);
2859 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2860
2861 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2862
2863 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2864 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2865 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2866 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2867 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2868 signed64 dividend = (signed32)(*rA);
2869 signed64 divisor = (signed32)(*rB);
2870 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2871 || (dividend == 0x80000000 && divisor == -1)) {
2872 if (OE)
2873 XER |= (xer_overflow | xer_summary_overflow);
2874 CR0_COMPARE(0, 0, Rc);
2875 }
2876 else {
2877 signed64 quotent = dividend / divisor;
2878 *rT = quotent;
2879 CR0_COMPARE((signed_word)quotent, 0, Rc);
2880 }
2881 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2882
2883 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2884
2885 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2886 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2887 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2888 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2889 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2890 unsigned64 dividend = (unsigned32)(*rA);
2891 unsigned64 divisor = (unsigned32)(*rB);
2892 if (divisor == 0) {
2893 if (OE)
2894 XER |= (xer_overflow | xer_summary_overflow);
2895 CR0_COMPARE(0, 0, Rc);
2896 }
2897 else {
2898 unsigned64 quotent = dividend / divisor;
2899 *rT = quotent;
2900 CR0_COMPARE((signed_word)quotent, 0, Rc);
2901 }
2902 ppc_insn_int2(my_index, processor, cpu_model(processor), rT, rA, rB, Rc);
2903
2904
2905 #
2906 # I.3.3.10 Fixed-Point Compare Instructions
2907 #
2908
2909 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2910 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2911 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2912 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2913 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2914 if (!is_64bit_mode && L)
2915 program_interrupt(processor, cia,
2916 illegal_instruction_program_interrupt);
2917 else {
2918 signed_word a;
2919 signed_word b = EXTS(SI);
2920 if (L == 0)
2921 a = EXTENDED(*rA);
2922 else
2923 a = *rA;
2924 CR_COMPARE(BF, a, b);
2925 }
2926 ppc_insn_int1_cr(my_index, processor, cpu_model(processor), BF, rA);
2927
2928 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2929 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2930 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2931 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2932 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2933 if (!is_64bit_mode && L)
2934 program_interrupt(processor, cia,
2935 illegal_instruction_program_interrupt);
2936 else {
2937 signed_word a;
2938 signed_word b;
2939 if (L == 0) {
2940 a = EXTENDED(*rA);
2941 b = EXTENDED(*rB);
2942 }
2943 else {
2944 a = *rA;
2945 b = *rB;
2946 }
2947 CR_COMPARE(BF, a, b);
2948 }
2949 ppc_insn_int2_cr(my_index, processor, cpu_model(processor), BF, rA, rB);
2950
2951 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2952 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2953 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2954 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2955 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2956 if (!is_64bit_mode && L)
2957 program_interrupt(processor, cia,
2958 illegal_instruction_program_interrupt);
2959 else {
2960 unsigned_word a;
2961 unsigned_word b = UI;
2962 if (L == 0)
2963 a = MASKED(*rA, 32, 63);
2964 else
2965 a = *rA;
2966 CR_COMPARE(BF, a, b);
2967 }
2968 ppc_insn_int1_cr(my_index, processor, cpu_model(processor), BF, rA);
2969
2970 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2971 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2972 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2973 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2974 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2975 if (!is_64bit_mode && L)
2976 program_interrupt(processor, cia,
2977 illegal_instruction_program_interrupt);
2978 else {
2979 unsigned_word a;
2980 unsigned_word b;
2981 if (L == 0) {
2982 a = MASKED(*rA, 32, 63);
2983 b = MASKED(*rB, 32, 63);
2984 }
2985 else {
2986 a = *rA;
2987 b = *rB;
2988 }
2989 CR_COMPARE(BF, a, b);
2990 }
2991 ppc_insn_int2_cr(my_index, processor, cpu_model(processor), BF, rA, rB);
2992
2993
2994 #
2995 # I.3.3.11 Fixed-Point Trap Instructions
2996 #
2997
2998 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2999 if (!is_64bit_mode)
3000 program_interrupt(processor, cia,
3001 illegal_instruction_program_interrupt);
3002 else {
3003 signed_word a = *rA;
3004 signed_word b = EXTS(SI);
3005 if ((a < b && TO{0})
3006 || (a > b && TO{1})
3007 || (a == b && TO{2})
3008 || ((unsigned_word)a < (unsigned_word)b && TO{3})
3009 || ((unsigned_word)a > (unsigned_word)b && TO{4})
3010 )
3011 program_interrupt(processor, cia,
3012 trap_program_interrupt);
3013 }
3014
3015 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
3016 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3017 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3018 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3019 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3020 signed_word a = EXTENDED(*rA);
3021 signed_word b = EXTS(SI);
3022 if ((a < b && TO{0})
3023 || (a > b && TO{1})
3024 || (a == b && TO{2})
3025 || ((unsigned_word)a < (unsigned_word)b && TO{3})
3026 || ((unsigned_word)a > (unsigned_word)b && TO{4})
3027 )
3028 program_interrupt(processor, cia,
3029 trap_program_interrupt);
3030
3031 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
3032 if (!is_64bit_mode)
3033 program_interrupt(processor, cia,
3034 illegal_instruction_program_interrupt);
3035 else {
3036 signed_word a = *rA;
3037 signed_word b = *rB;
3038 if ((a < b && TO{0})
3039 || (a > b && TO{1})
3040 || (a == b && TO{2})
3041 || ((unsigned_word)a < (unsigned_word)b && TO{3})
3042 || ((unsigned_word)a > (unsigned_word)b && TO{4})
3043 )
3044 program_interrupt(processor, cia,
3045 trap_program_interrupt);
3046 }
3047
3048 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
3049 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3050 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3051 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3052 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3053 signed_word a = EXTENDED(*rA);
3054 signed_word b = EXTENDED(*rB);
3055 if (TO == 12 && rA == rB) {
3056 ITRACE(trace_breakpoint, ("breakpoint\n"));
3057 cpu_halt(processor, cia, was_trap, 0);
3058 }
3059 else if ((a < b && TO{0})
3060 || (a > b && TO{1})
3061 || (a == b && TO{2})
3062 || ((unsigned_word)a < (unsigned_word)b && TO{3})
3063 || ((unsigned_word)a > (unsigned_word)b && TO{4})
3064 )
3065 program_interrupt(processor, cia,
3066 trap_program_interrupt);
3067
3068 #
3069 # I.3.3.12 Fixed-Point Logical Instructions
3070 #
3071
3072 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
3073 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3074 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3075 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3076 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3077 *rA = *rS & UI;
3078 CR0_COMPARE(*rA, 0, 1/*Rc*/);
3079 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 1/*Rc*/);
3080
3081 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
3082 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3083 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3084 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3085 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3086 *rA = *rS & (UI << 16);
3087 CR0_COMPARE(*rA, 0, 1/*Rc*/);
3088 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 1/*Rc*/);
3089
3090 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
3091 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3092 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3093 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3094 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3095 *rA = *rS | UI;
3096 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3097
3098 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
3099 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3100 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3101 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3102 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3103 *rA = *rS | (UI << 16);
3104 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3105
3106 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
3107 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3108 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3109 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3110 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3111 *rA = *rS ^ UI;
3112 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3113
3114 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
3115 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3116 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3117 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3118 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3119 *rA = *rS ^ (UI << 16);
3120 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, 0);
3121
3122 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
3123 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3124 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3125 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3126 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3127 *rA = *rS & *rB;
3128 CR0_COMPARE(*rA, 0, Rc);
3129 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3130
3131 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
3132 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3133 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3134 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3135 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3136 *rA = *rS | *rB;
3137 CR0_COMPARE(*rA, 0, Rc);
3138 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3139
3140 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
3141 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3142 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3143 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3144 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3145 *rA = *rS ^ *rB;
3146 CR0_COMPARE(*rA, 0, Rc);
3147 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3148
3149 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
3150 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3151 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3152 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3153 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3154 *rA = ~(*rS & *rB);
3155 CR0_COMPARE(*rA, 0, Rc);
3156 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3157
3158 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
3159 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3160 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3161 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3162 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3163 *rA = ~(*rS | *rB);
3164 CR0_COMPARE(*rA, 0, Rc);
3165 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3166
3167 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
3168 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3169 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3170 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3171 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3172 # *rA = ~(*rS ^ *rB); /* A === B */
3173 # CR0_COMPARE(*rA, 0, Rc);
3174
3175 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
3176 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3177 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3178 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3179 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3180 *rA = *rS & ~*rB;
3181 CR0_COMPARE(*rA, 0, Rc);
3182 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3183
3184 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
3185 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3186 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3187 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3188 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3189 *rA = *rS | ~*rB;
3190 CR0_COMPARE(*rA, 0, Rc);
3191 ppc_insn_int2(my_index, processor, cpu_model(processor), rA, rS, rB, Rc);
3192
3193 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
3194 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3195 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3196 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3197 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3198 *rA = (signed_word)(signed8)*rS;
3199 CR0_COMPARE(*rA, 0, Rc);
3200 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3201
3202 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
3203 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3204 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3205 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3206 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3207 *rA = (signed_word)(signed16)*rS;
3208 CR0_COMPARE(*rA, 0, Rc);
3209 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3210
3211 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
3212 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3213 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3214 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3215 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3216 # *rA = (signed_word)(signed32)*rS;
3217 # CR0_COMPARE(*rA, 0, Rc);
3218
3219 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
3220 # int count = 0;
3221 # unsigned64 mask = BIT64(0);
3222 # unsigned64 source = *rS;
3223 # while (!(source & mask) && mask != 0) {
3224 # mask >>= 1;
3225 # count++;
3226 # }
3227 # *rA = count;
3228 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3229
3230 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
3231 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3232 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3233 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3234 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3235 int count = 0;
3236 unsigned32 mask = BIT32(0);
3237 unsigned32 source = *rS;
3238 while (!(source & mask) && mask != 0) {
3239 mask >>= 1;
3240 count++;
3241 }
3242 *rA = count;
3243 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3244
3245
3246 #
3247 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
3248 #
3249
3250 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
3251 # long n = (sh_5 << 4) | sh_0_4;
3252 # unsigned_word r = ROTL64(*rS, n);
3253 # long b = (mb_5 << 4) | mb_0_4;
3254 # unsigned_word m = MASK(b, 63);
3255 # signed_word result = r & m;
3256 # *rA = result;
3257 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3258
3259 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
3260 # long n = (sh_5 << 4) | sh_0_4;
3261 # unsigned_word r = ROTL64(*rS, n);
3262 # long e = (me_5 << 4) | me_0_4;
3263 # unsigned_word m = MASK(0, e);
3264 # signed_word result = r & m;
3265 # *rA = result;
3266 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3267
3268 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
3269 # long n = (sh_5 << 4) | sh_0_4;
3270 # unsigned_word r = ROTL64(*rS, n);
3271 # long b = (mb_5 << 4) | mb_0_4;
3272 # unsigned_word m = MASK(0, (64-n));
3273 # signed_word result = r & m;
3274 # *rA = result;
3275 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3276
3277 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
3278 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3279 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3280 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3281 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3282 long n = SH;
3283 unsigned32 s = *rS;
3284 unsigned32 r = ROTL32(s, n);
3285 unsigned32 m = MASK(MB+32, ME+32);
3286 signed_word result = r & m;
3287 *rA = result;
3288 CR0_COMPARE(result, 0, Rc);
3289 ITRACE(trace_alu,
3290 ("n=%d, s=0x%x, r=0x%x, m=0x%x, result=0x%x, cr=0x%x\n",
3291 n, s, r, m, result, CR));
3292 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3293
3294 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
3295 # long n = MASKED(*rB, 58, 63);
3296 # unsigned_word r = ROTL64(*rS, n);
3297 # long b = (mb_5 << 4) | mb_0_4;
3298 # unsigned_word m = MASK(b, 63);
3299 # signed_word result = r & m;
3300 # *rA = result;
3301 # CR0_COMPARE(result, 0, Rc);
3302
3303 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
3304 # long n = MASKED(*rB, 58, 63);
3305 # unsigned_word r = ROTL64(*rS, n);
3306 # long e = (me_5 << 4) | me_0_4;
3307 # unsigned_word m = MASK(0, e);
3308 # signed_word result = r & m;
3309 # *rA = result;
3310 # CR0_COMPARE(result, 0, Rc);
3311
3312 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
3313 # long n = MASKED(*rB, 59, 63);
3314 # unsigned32 r = ROTL32(*rS, n);
3315 # unsigned32 m = MASK(MB+32, ME+32);
3316 # signed_word result = r & m;
3317 # *rA = result;
3318 # CR0_COMPARE(result, 0, Rc);
3319
3320 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
3321 # long n = (sh_5 << 4) | sh_0_4;
3322 # unsigned_word r = ROTL64(*rS, n);
3323 # long b = (mb_5 << 4) | mb_0_4;
3324 # unsigned_word m = MASK(b, (64-n));
3325 # signed_word result = (r & m) | (*rA & ~m)
3326 # *rA = result;
3327 # CR0_COMPARE(result, 0, Rc);
3328
3329 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
3330 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3331 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3332 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3333 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3334 long n = SH;
3335 unsigned32 r = ROTL32(*rS, n);
3336 unsigned32 m = MASK(MB+32, ME+32);
3337 signed_word result = (r & m) | (*rA & ~m);
3338 *rA = result;
3339 ITRACE(trace_alu, (": n=%d *rS=0x%x r=0x%x m=0x%x result=0x%x\n",
3340 n, *rS, r, m, result));
3341 CR0_COMPARE(result, 0, Rc);
3342 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3343
3344
3345 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
3346
3347 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
3348 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3349 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3350 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3351 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3352 int n = MASKED(*rB, 59, 63);
3353 unsigned32 source = *rS;
3354 signed_word shifted;
3355 if (n < 32)
3356 shifted = (source << n);
3357 else
3358 shifted = 0;
3359 *rA = shifted;
3360 CR0_COMPARE(shifted, 0, Rc);
3361 ITRACE(trace_alu,
3362 ("n=%d, source=0x%x, shifted=0x%x\n",
3363 n, source, shifted));
3364 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3365
3366 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3367
3368 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
3369 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3370 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3371 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3372 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3373 int n = MASKED(*rB, 59, 63);
3374 unsigned32 source = *rS;
3375 signed_word shifted;
3376 if (n < 32)
3377 shifted = (source >> n);
3378 else
3379 shifted = 0;
3380 *rA = shifted;
3381 CR0_COMPARE(shifted, 0, Rc);
3382 ITRACE(trace_alu, \
3383 ("n=%d, source=0x%x, shifted=0x%x\n",
3384 n, source, shifted));
3385 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3386
3387 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3388
3389 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3390 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3391 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3392 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3393 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3394 int n = SH;
3395 signed_word r = ROTL32(*rS, /*64*/32-n);
3396 signed_word m = MASK(n+32, 63);
3397 int S = MASKED(*rS, 32, 32);
3398 signed_word shifted = (r & m) | (S ? ~m : 0);
3399 *rA = shifted;
3400 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3401 XER |= xer_carry;
3402 else
3403 XER &= ~xer_carry;
3404 CR0_COMPARE(shifted, 0, Rc);
3405 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3406
3407 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3408
3409 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3410 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3411 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3412 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3413 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3414 int n = MASKED(*rB, 58, 63);
3415 int shift = (n >= 31 ? 31 : n);
3416 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3417 signed32 shifted = source >> shift;
3418 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
3419 *rA = (signed_word)shifted; /* if 64bit will sign extend */
3420 if (source < 0 && (source & mask))
3421 XER |= xer_carry;
3422 else
3423 XER &= ~xer_carry;
3424 CR0_COMPARE(shifted, 0, Rc);
3425 ppc_insn_int1(my_index, processor, cpu_model(processor), rA, rS, Rc);
3426
3427 #
3428 # I.3.3.14 Move to/from System Register Instructions
3429 #
3430
3431 0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3432 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3433 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3434 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3435 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3436 int n = (spr{5:9} << 5) | spr{0:4};
3437 if (spr{0} && IS_PROBLEM_STATE(processor))
3438 program_interrupt(processor, cia,
3439 privileged_instruction_program_interrupt);
3440 else if (!spr_is_valid(n)
3441 || spr_is_readonly(n))
3442 program_interrupt(processor, cia,
3443 illegal_instruction_program_interrupt);
3444 else {
3445 spreg new_val = (spr_length(n) == 64
3446 ? *rS
3447 : MASKED(*rS, 32, 63));
3448 /* HACK - time base registers need to be updated immediatly */
3449 if (WITH_TIME_BASE) {
3450 signed64 time_base;
3451 switch (n) {
3452 case spr_tbu:
3453 cpu_set_time_base(processor,
3454 (MASKED64(cpu_get_time_base(processor), 32, 63)
3455 | INSERTED64(new_val, 0, 31)));
3456 break;
3457 case spr_tbl:
3458 cpu_set_time_base(processor,
3459 (MASKED64(cpu_get_time_base(processor), 0, 31)
3460 | INSERTED64(new_val, 32, 63)));
3461 break;
3462 case spr_dec:
3463 cpu_set_decrementer(processor, new_val);
3464 break;
3465 default:
3466 SPREG(n) = new_val;
3467 break;
3468 }
3469 }
3470 else {
3471 SPREG(n) = new_val;
3472 }
3473 }
3474 ppc_insn_to_spr(my_index, processor, cpu_model(processor), n, rS);
3475
3476 0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3477 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3478 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3479 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3480 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3481 int n = (spr{5:9} << 5) | spr{0:4};
3482 if (spr{0} && IS_PROBLEM_STATE(processor))
3483 program_interrupt(processor, cia,
3484 privileged_instruction_program_interrupt);
3485 else if (!spr_is_valid(n))
3486 program_interrupt(processor, cia,
3487 illegal_instruction_program_interrupt);
3488 else {
3489 /* HACK - some SPR's need to get their value extracted specially */
3490 *rT = SPREG(n);
3491 }
3492 ppc_insn_from_spr(my_index, processor, cpu_model(processor), rT, n);
3493
3494 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3495 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3496 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3497 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3498 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3499 if (FXM == 0xff) {
3500 CR = *rS;
3501 }
3502 else {
3503 unsigned_word mask = 0;
3504 unsigned_word f;
3505 for (f = 0; f < 8; f++) {
3506 if (FXM & (0x80 >> f))
3507 mask |= (0xf << 4*(7-f));
3508 }
3509 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3510 }
3511 ppc_insn_mtcr(my_index, processor, cpu_model(processor), rS, FXM);
3512
3513 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3514
3515 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3516 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3517 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3518 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3519 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3520 *rT = (unsigned32)CR;
3521 ppc_insn_mfcr(my_index, processor, cpu_model(processor), rT);
3522
3523 #
3524 # I.4.6.2 Floating-Point Load Instructions
3525 #
3526
3527 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3528 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3529 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3530 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3531 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3532 unsigned_word b;
3533 unsigned_word EA;
3534 if (RA == 0) b = 0;
3535 else b = *rA;
3536 EA = b + EXTS(D);
3537 *frT = DOUBLE(MEM(unsigned, EA, 4));
3538 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 0/*RA_is_update*/);
3539
3540 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3541 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3542 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3543 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3544 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3545 unsigned_word b;
3546 unsigned_word EA;
3547 if (RA == 0) b = 0;
3548 else b = *rA;
3549 EA = b + *rB;
3550 *frT = DOUBLE(MEM(unsigned, EA, 4));
3551 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 0/*RA_is_update*/);
3552
3553 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3554 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3555 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3556 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3557 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3558 unsigned_word EA;
3559 if (RA == 0)
3560 program_interrupt(processor, cia,
3561 illegal_instruction_program_interrupt);
3562 EA = *rA + EXTS(D);
3563 *frT = DOUBLE(MEM(unsigned, EA, 4));
3564 *rA = EA;
3565 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 1/*RA_is_update*/);
3566
3567 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3568 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3569 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3570 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3571 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3572 unsigned_word EA;
3573 if (RA == 0)
3574 program_interrupt(processor, cia,
3575 illegal_instruction_program_interrupt);
3576 EA = *rA + *rB;
3577 *frT = DOUBLE(MEM(unsigned, EA, 4));
3578 *rA = EA;
3579 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 1/*RA_is_update*/);
3580
3581 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3582 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3583 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3584 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3585 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3586 unsigned_word b;
3587 unsigned_word EA;
3588 if (RA == 0) b = 0;
3589 else b = *rA;
3590 EA = b + EXTS(D);
3591 *frT = MEM(unsigned, EA, 8);
3592 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 0/*RA_is_update*/);
3593
3594 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3595 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3596 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3597 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3598 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3599 unsigned_word b;
3600 unsigned_word EA;
3601 if (RA == 0) b = 0;
3602 else b = *rA;
3603 EA = b + *rB;
3604 *frT = MEM(unsigned, EA, 8);
3605 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 0/*RA_is_update*/);
3606
3607 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3608 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3609 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3610 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3611 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3612 unsigned_word EA;
3613 if (RA == 0)
3614 program_interrupt(processor, cia,
3615 illegal_instruction_program_interrupt);
3616 EA = *rA + EXTS(D);
3617 *frT = MEM(unsigned, EA, 8);
3618 *rA = EA;
3619 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frT, rA, 0/*RD_is_output*/, 1/*RA_is_update*/);
3620
3621 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3622 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3623 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3624 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3625 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3626 unsigned_word EA;
3627 if (RA == 0)
3628 program_interrupt(processor, cia,
3629 illegal_instruction_program_interrupt);
3630 EA = *rA + *rB;
3631 *frT = MEM(unsigned, EA, 8);
3632 *rA = EA;
3633 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frT, rA, rB, 0/*RD_is_output*/, 1/*RA_is_update*/);
3634
3635
3636 #
3637 # I.4.6.3 Floating-Point Store Instructions
3638 #
3639
3640 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3641 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3642 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3643 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3644 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3645 unsigned_word b;
3646 unsigned_word EA;
3647 if (RA == 0) b = 0;
3648 else b = *rA;
3649 EA = b + EXTS(D);
3650 STORE(EA, 4, SINGLE(*frS));
3651 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 0/*RA_is_update*/);
3652
3653 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3654 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3655 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3656 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3657 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3658 unsigned_word b;
3659 unsigned_word EA;
3660 if (RA == 0) b = 0;
3661 else b = *rA;
3662 EA = b + *rB;
3663 STORE(EA, 4, SINGLE(*frS));
3664 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 0/*RA_is_update*/);
3665
3666 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3667 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3668 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3669 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3670 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3671 unsigned_word EA;
3672 if (RA == 0)
3673 program_interrupt(processor, cia,
3674 illegal_instruction_program_interrupt);
3675 EA = *rA + EXTS(D);
3676 STORE(EA, 4, SINGLE(*frS));
3677 *rA = EA;
3678 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 1/*RA_is_update*/);
3679
3680 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3681 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3682 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3683 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3684 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3685 unsigned_word EA;
3686 if (RA == 0)
3687 program_interrupt(processor, cia,
3688 illegal_instruction_program_interrupt);
3689 EA = *rA + *rB;
3690 STORE(EA, 4, SINGLE(*frS));
3691 *rA = EA;
3692 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 1/*RA_is_update*/);
3693
3694 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3695 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3696 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3697 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3698 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3699 unsigned_word b;
3700 unsigned_word EA;
3701 if (RA == 0) b = 0;
3702 else b = *rA;
3703 EA = b + EXTS(D);
3704 STORE(EA, 8, *frS);
3705 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 0/*RA_is_update*/);
3706
3707 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3708 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3709 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3710 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3711 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3712 unsigned_word b;
3713 unsigned_word EA;
3714 if (RA == 0) b = 0;
3715 else b = *rA;
3716 EA = b + *rB;
3717 STORE(EA, 8, *frS);
3718 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 0/*RA_is_update*/);
3719
3720 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3721 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3722 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3723 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3724 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3725 unsigned_word EA;
3726 if (RA == 0)
3727 program_interrupt(processor, cia,
3728 illegal_instruction_program_interrupt);
3729 EA = *rA + EXTS(D);
3730 STORE(EA, 8, *frS);
3731 *rA = EA;
3732 ppc_insn_int1_fp1(my_index, processor, cpu_model(processor), frS, rA, 1/*RD_is_output*/, 1/*RA_is_update*/);
3733
3734 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3735 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3736 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3737 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3738 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3739 unsigned_word EA;
3740 if (RA == 0)
3741 program_interrupt(processor, cia,
3742 illegal_instruction_program_interrupt);
3743 EA = *rA + *rB;
3744 STORE(EA, 8, *frS);
3745 *rA = EA;
3746 ppc_insn_int2_fp1(my_index, processor, cpu_model(processor), frS, rA, rB, 1/*RD_is_output*/, 1/*RA_is_update*/);
3747
3748
3749 #
3750 # I.4.6.4 Floating-Point Move Instructions
3751 #
3752
3753 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3754 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3755 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3756 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3757 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3758 *frT = *frB;
3759 CR1_UPDATE(Rc);
3760 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3761
3762 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3763 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3764 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3765 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3766 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3767 *frT = *frB ^ BIT64(0);
3768 CR1_UPDATE(Rc);
3769 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3770
3771 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3772 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3773 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3774 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3775 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3776 *frT = *frB & ~BIT64(0);
3777 CR1_UPDATE(Rc);
3778 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3779
3780 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3781 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3782 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3783 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3784 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3785 *frT = *frB | BIT64(0);
3786 CR1_UPDATE(Rc);
3787 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
3788
3789
3790
3791 #
3792 # I.4.6.5 Floating-Point Arithmetic Instructions
3793 #
3794
3795 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3796 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3797 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3798 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3799 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3800 FPSCR_BEGIN;
3801 if (is_invalid_operation(processor, cia,
3802 *frA, *frB,
3803 fpscr_vxsnan | fpscr_vxisi,
3804 0, /*single?*/
3805 0) /*negate?*/) {
3806 invalid_arithemetic_operation(processor, cia,
3807 frT, *frA, *frB, 0,
3808 0, /*instruction_is_frsp*/
3809 0, /*instruction_is_convert_to_64bit*/
3810 0, /*instruction_is_convert_to_32bit*/
3811 0); /*single-precision*/
3812 }
3813 else {
3814 /*HACK!*/
3815 double s = *(double*)frA + *(double*)frB;
3816 *(double*)frT = s;
3817 }
3818 FPSCR_END(Rc);
3819 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3820
3821 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3822 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3823 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3824 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3825 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3826 FPSCR_BEGIN;
3827 if (is_invalid_operation(processor, cia,
3828 *frA, *frB,
3829 fpscr_vxsnan | fpscr_vxisi,
3830 1, /*single?*/
3831 0) /*negate?*/) {
3832 invalid_arithemetic_operation(processor, cia,
3833 frT, *frA, *frB, 0,
3834 0, /*instruction_is_frsp*/
3835 0, /*instruction_is_convert_to_64bit*/
3836 0, /*instruction_is_convert_to_32bit*/
3837 1); /*single-precision*/
3838 }
3839 else {
3840 /*HACK!*/
3841 float s = *(double*)frA + *(double*)frB;
3842 *(double*)frT = s;
3843 }
3844 FPSCR_END(Rc);
3845 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3846
3847 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3848 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3849 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3850 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3851 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3852 FPSCR_BEGIN;
3853 if (is_invalid_operation(processor, cia,
3854 *frA, *frB,
3855 fpscr_vxsnan | fpscr_vxisi,
3856 0, /*single?*/
3857 1) /*negate?*/) {
3858 invalid_arithemetic_operation(processor, cia,
3859 frT, *frA, *frB, 0,
3860 0, /*instruction_is_frsp*/
3861 0, /*instruction_is_convert_to_64bit*/
3862 0, /*instruction_is_convert_to_32bit*/
3863 0); /*single-precision*/
3864 }
3865 else {
3866 /*HACK!*/
3867 double s = *(double*)frA - *(double*)frB;
3868 *(double*)frT = s;
3869 }
3870 FPSCR_END(Rc);
3871 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3872
3873 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3874 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3875 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3876 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3877 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3878 FPSCR_BEGIN;
3879 if (is_invalid_operation(processor, cia,
3880 *frA, *frB,
3881 fpscr_vxsnan | fpscr_vxisi,
3882 1, /*single?*/
3883 1) /*negate?*/) {
3884 invalid_arithemetic_operation(processor, cia,
3885 frT, *frA, *frB, 0,
3886 0, /*instruction_is_frsp*/
3887 0, /*instruction_is_convert_to_64bit*/
3888 0, /*instruction_is_convert_to_32bit*/
3889 1); /*single-precision*/
3890 }
3891 else {
3892 /*HACK!*/
3893 float s = *(double*)frA - *(double*)frB;
3894 *(double*)frT = s;
3895 }
3896 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3897 FPSCR_END(Rc);
3898
3899 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3900 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3901 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3902 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3903 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3904 FPSCR_BEGIN;
3905 if (is_invalid_operation(processor, cia,
3906 *frA, *frC,
3907 fpscr_vxsnan | fpscr_vximz,
3908 0, /*single?*/
3909 0) /*negate?*/) {
3910 invalid_arithemetic_operation(processor, cia,
3911 frT, *frA, 0, *frC,
3912 0, /*instruction_is_frsp*/
3913 0, /*instruction_is_convert_to_64bit*/
3914 0, /*instruction_is_convert_to_32bit*/
3915 0); /*single-precision*/
3916 }
3917 else {
3918 /*HACK!*/
3919 double s = *(double*)frA * *(double*)frC;
3920 *(double*)frT = s;
3921 }
3922 FPSCR_END(Rc);
3923 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frC, Rc);
3924
3925 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3926 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3927 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3928 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3929 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3930 FPSCR_BEGIN;
3931 if (is_invalid_operation(processor, cia,
3932 *frA, *frC,
3933 fpscr_vxsnan | fpscr_vximz,
3934 1, /*single?*/
3935 0) /*negate?*/) {
3936 invalid_arithemetic_operation(processor, cia,
3937 frT, *frA, 0, *frC,
3938 0, /*instruction_is_frsp*/
3939 0, /*instruction_is_convert_to_64bit*/
3940 0, /*instruction_is_convert_to_32bit*/
3941 1); /*single-precision*/
3942 }
3943 else {
3944 /*HACK!*/
3945 float s = *(double*)frA * *(double*)frC;
3946 *(double*)frT = s;
3947 }
3948 FPSCR_END(Rc);
3949 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frC, Rc);
3950
3951 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3952 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3953 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3954 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3955 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3956 FPSCR_BEGIN;
3957 if (is_invalid_operation(processor, cia,
3958 *frA, *frB,
3959 fpscr_vxsnan | fpscr_vxzdz,
3960 0, /*single?*/
3961 0) /*negate?*/) {
3962 invalid_arithemetic_operation(processor, cia,
3963 frT, *frA, *frB, 0,
3964 0, /*instruction_is_frsp*/
3965 0, /*instruction_is_convert_to_64bit*/
3966 0, /*instruction_is_convert_to_32bit*/
3967 0); /*single-precision*/
3968 }
3969 else {
3970 /*HACK!*/
3971 double s = *(double*)frA / *(double*)frB;
3972 *(double*)frT = s;
3973 }
3974 FPSCR_END(Rc);
3975 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
3976
3977 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3978 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3979 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3980 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3981 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3982 FPSCR_BEGIN;
3983 if (is_invalid_operation(processor, cia,
3984 *frA, *frB,
3985 fpscr_vxsnan | fpscr_vxzdz,
3986 1, /*single?*/
3987 0) /*negate?*/) {
3988 invalid_arithemetic_operation(processor, cia,
3989 frT, *frA, *frB, 0,
3990 0, /*instruction_is_frsp*/
3991 0, /*instruction_is_convert_to_64bit*/
3992 0, /*instruction_is_convert_to_32bit*/
3993 1); /*single-precision*/
3994 }
3995 else {
3996 /*HACK!*/
3997 float s = *(double*)frA / *(double*)frB;
3998 *(double*)frT = s;
3999 }
4000 FPSCR_END(Rc);
4001 ppc_insn_fp2(my_index, processor, cpu_model(processor), frT, frA, frB, Rc);
4002
4003 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
4004 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4005 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4006 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4007 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4008 FPSCR_BEGIN;
4009 double product; /*HACK! - incorrectly loosing precision ... */
4010 /* compute the multiply */
4011 if (is_invalid_operation(processor, cia,
4012 *frA, *frC,
4013 fpscr_vxsnan | fpscr_vximz,
4014 0, /*single?*/
4015 0) /*negate?*/) {
4016 invalid_arithemetic_operation(processor, cia,
4017 (unsigned64*)&product, *frA, 0, *frC,
4018 0, /*instruction_is_frsp*/
4019 0, /*instruction_is_convert_to_64bit*/
4020 0, /*instruction_is_convert_to_32bit*/
4021 0); /*single-precision*/
4022 }
4023 else {
4024 /*HACK!*/
4025 product = *(double*)frA * *(double*)frC;
4026 }
4027 /* compute the add */
4028 if (is_invalid_operation(processor, cia,
4029 product, *frB,
4030 fpscr_vxsnan | fpscr_vxisi,
4031 0, /*single?*/
4032 0) /*negate?*/) {
4033 invalid_arithemetic_operation(processor, cia,
4034 frT, product, *frB, 0,
4035 0, /*instruction_is_frsp*/
4036 0, /*instruction_is_convert_to_64bit*/
4037 0, /*instruction_is_convert_to_32bit*/
4038 0); /*single-precision*/
4039 }
4040 else {
4041 /*HACK!*/
4042 double s = product + *(double*)frB;
4043 *(double*)frT = s;
4044 }
4045 FPSCR_END(Rc);
4046 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4047
4048 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
4049 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4050 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4051 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4052 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4053 FPSCR_BEGIN;
4054 float product; /*HACK! - incorrectly loosing precision ... */
4055 /* compute the multiply */
4056 if (is_invalid_operation(processor, cia,
4057 *frA, *frC,
4058 fpscr_vxsnan | fpscr_vximz,
4059 1, /*single?*/
4060 0) /*negate?*/) {
4061 invalid_arithemetic_operation(processor, cia,
4062 (unsigned64*)&product, *frA, 0, *frC,
4063 0, /*instruction_is_frsp*/
4064 0, /*instruction_is_convert_to_64bit*/
4065 0, /*instruction_is_convert_to_32bit*/
4066 0); /*single-precision*/
4067 }
4068 else {
4069 /*HACK!*/
4070 product = *(double*)frA * *(double*)frC;
4071 }
4072 /* compute the add */
4073 if (is_invalid_operation(processor, cia,
4074 product, *frB,
4075 fpscr_vxsnan | fpscr_vxisi,
4076 1, /*single?*/
4077 0) /*negate?*/) {
4078 invalid_arithemetic_operation(processor, cia,
4079 frT, product, *frB, 0,
4080 0, /*instruction_is_frsp*/
4081 0, /*instruction_is_convert_to_64bit*/
4082 0, /*instruction_is_convert_to_32bit*/
4083 0); /*single-precision*/
4084 }
4085 else {
4086 /*HACK!*/
4087 float s = product + *(double*)frB;
4088 *(double*)frT = (double)s;
4089 }
4090 FPSCR_END(Rc);
4091 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4092
4093 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
4094 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4095 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4096 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4097 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4098 FPSCR_BEGIN;
4099 double product; /*HACK! - incorrectly loosing precision ... */
4100 /* compute the multiply */
4101 if (is_invalid_operation(processor, cia,
4102 *frA, *frC,
4103 fpscr_vxsnan | fpscr_vximz,
4104 0, /*single?*/
4105 0) /*negate?*/) {
4106 invalid_arithemetic_operation(processor, cia,
4107 (unsigned64*)&product, *frA, 0, *frC,
4108 0, /*instruction_is_frsp*/
4109 0, /*instruction_is_convert_to_64bit*/
4110 0, /*instruction_is_convert_to_32bit*/
4111 0); /*single-precision*/
4112 }
4113 else {
4114 /*HACK!*/
4115 product = *(double*)frA * *(double*)frC;
4116 }
4117 /* compute the subtract */
4118 if (is_invalid_operation(processor, cia,
4119 product, *frB,
4120 fpscr_vxsnan | fpscr_vxisi,
4121 0, /*single?*/
4122 0) /*negate?*/) {
4123 invalid_arithemetic_operation(processor, cia,
4124 frT, product, *frB, 0,
4125 0, /*instruction_is_frsp*/
4126 0, /*instruction_is_convert_to_64bit*/
4127 0, /*instruction_is_convert_to_32bit*/
4128 0); /*single-precision*/
4129 }
4130 else {
4131 /*HACK!*/
4132 double s = product - *(double*)frB;
4133 *(double*)frT = s;
4134 }
4135 FPSCR_END(Rc);
4136 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4137
4138 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
4139 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4140 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4141 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4142 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4143 FPSCR_BEGIN;
4144 float product; /*HACK! - incorrectly loosing precision ... */
4145 /* compute the multiply */
4146 if (is_invalid_operation(processor, cia,
4147 *frA, *frC,
4148 fpscr_vxsnan | fpscr_vximz,
4149 1, /*single?*/
4150 0) /*negate?*/) {
4151 invalid_arithemetic_operation(processor, cia,
4152 (unsigned64*)&product, *frA, 0, *frC,
4153 0, /*instruction_is_frsp*/
4154 0, /*instruction_is_convert_to_64bit*/
4155 0, /*instruction_is_convert_to_32bit*/
4156 0); /*single-precision*/
4157 }
4158 else {
4159 /*HACK!*/
4160 product = *(double*)frA * *(double*)frC;
4161 }
4162 /* compute the subtract */
4163 if (is_invalid_operation(processor, cia,
4164 product, *frB,
4165 fpscr_vxsnan | fpscr_vxisi,
4166 1, /*single?*/
4167 0) /*negate?*/) {
4168 invalid_arithemetic_operation(processor, cia,
4169 frT, product, *frB, 0,
4170 0, /*instruction_is_frsp*/
4171 0, /*instruction_is_convert_to_64bit*/
4172 0, /*instruction_is_convert_to_32bit*/
4173 0); /*single-precision*/
4174 }
4175 else {
4176 /*HACK!*/
4177 float s = product - *(double*)frB;
4178 *(double*)frT = (double)s;
4179 }
4180 FPSCR_END(Rc);
4181 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4182
4183 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
4184 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4185 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4186 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4187 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4188 FPSCR_BEGIN;
4189 double product; /*HACK! - incorrectly loosing precision ... */
4190 /* compute the multiply */
4191 if (is_invalid_operation(processor, cia,
4192 *frA, *frC,
4193 fpscr_vxsnan | fpscr_vximz,
4194 0, /*single?*/
4195 0) /*negate?*/) {
4196 invalid_arithemetic_operation(processor, cia,
4197 (unsigned64*)&product, *frA, 0, *frC,
4198 0, /*instruction_is_frsp*/
4199 0, /*instruction_is_convert_to_64bit*/
4200 0, /*instruction_is_convert_to_32bit*/
4201 0); /*single-precision*/
4202 }
4203 else {
4204 /*HACK!*/
4205 product = *(double*)frA * *(double*)frC;
4206 }
4207 /* compute the add */
4208 if (is_invalid_operation(processor, cia,
4209 product, *frB,
4210 fpscr_vxsnan | fpscr_vxisi,
4211 0, /*single?*/
4212 0) /*negate?*/) {
4213 invalid_arithemetic_operation(processor, cia,
4214 frT, product, *frB, 0,
4215 0, /*instruction_is_frsp*/
4216 0, /*instruction_is_convert_to_64bit*/
4217 0, /*instruction_is_convert_to_32bit*/
4218 0); /*single-precision*/
4219 }
4220 else {
4221 /*HACK!*/
4222 double s = -(product + *(double*)frB);
4223 *(double*)frT = s;
4224 }
4225 FPSCR_END(Rc);
4226 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4227
4228 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
4229 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4230 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4231 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4232 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4233 FPSCR_BEGIN;
4234 float product; /*HACK! - incorrectly loosing precision ... */
4235 /* compute the multiply */
4236 if (is_invalid_operation(processor, cia,
4237 *frA, *frC,
4238 fpscr_vxsnan | fpscr_vximz,
4239 1, /*single?*/
4240 0) /*negate?*/) {
4241 invalid_arithemetic_operation(processor, cia,
4242 (unsigned64*)&product, *frA, 0, *frC,
4243 0, /*instruction_is_frsp*/
4244 0, /*instruction_is_convert_to_64bit*/
4245 0, /*instruction_is_convert_to_32bit*/
4246 0); /*single-precision*/
4247 }
4248 else {
4249 /*HACK!*/
4250 product = *(double*)frA * *(double*)frC;
4251 }
4252 /* compute the add */
4253 if (is_invalid_operation(processor, cia,
4254 product, *frB,
4255 fpscr_vxsnan | fpscr_vxisi,
4256 1, /*single?*/
4257 0) /*negate?*/) {
4258 invalid_arithemetic_operation(processor, cia,
4259 frT, product, *frB, 0,
4260 0, /*instruction_is_frsp*/
4261 0, /*instruction_is_convert_to_64bit*/
4262 0, /*instruction_is_convert_to_32bit*/
4263 0); /*single-precision*/
4264 }
4265 else {
4266 /*HACK!*/
4267 float s = -(product + *(double*)frB);
4268 *(double*)frT = (double)s;
4269 }
4270 FPSCR_END(Rc);
4271 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4272
4273 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
4274 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4275 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4276 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4277 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4278 FPSCR_BEGIN;
4279 double product; /*HACK! - incorrectly loosing precision ... */
4280 /* compute the multiply */
4281 if (is_invalid_operation(processor, cia,
4282 *frA, *frC,
4283 fpscr_vxsnan | fpscr_vximz,
4284 0, /*single?*/
4285 0) /*negate?*/) {
4286 invalid_arithemetic_operation(processor, cia,
4287 (unsigned64*)&product, *frA, 0, *frC,
4288 0, /*instruction_is_frsp*/
4289 0, /*instruction_is_convert_to_64bit*/
4290 0, /*instruction_is_convert_to_32bit*/
4291 0); /*single-precision*/
4292 }
4293 else {
4294 /*HACK!*/
4295 product = *(double*)frA * *(double*)frC;
4296 }
4297 /* compute the subtract */
4298 if (is_invalid_operation(processor, cia,
4299 product, *frB,
4300 fpscr_vxsnan | fpscr_vxisi,
4301 0, /*single?*/
4302 0) /*negate?*/) {
4303 invalid_arithemetic_operation(processor, cia,
4304 frT, product, *frB, 0,
4305 0, /*instruction_is_frsp*/
4306 0, /*instruction_is_convert_to_64bit*/
4307 0, /*instruction_is_convert_to_32bit*/
4308 0); /*single-precision*/
4309 }
4310 else {
4311 /*HACK!*/
4312 double s = -(product - *(double*)frB);
4313 *(double*)frT = s;
4314 }
4315 FPSCR_END(Rc);
4316 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4317
4318 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
4319 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4320 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4321 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4322 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4323 FPSCR_BEGIN;
4324 float product; /*HACK! - incorrectly loosing precision ... */
4325 /* compute the multiply */
4326 if (is_invalid_operation(processor, cia,
4327 *frA, *frC,
4328 fpscr_vxsnan | fpscr_vximz,
4329 1, /*single?*/
4330 0) /*negate?*/) {
4331 invalid_arithemetic_operation(processor, cia,
4332 (unsigned64*)&product, *frA, 0, *frC,
4333 0, /*instruction_is_frsp*/
4334 0, /*instruction_is_convert_to_64bit*/
4335 0, /*instruction_is_convert_to_32bit*/
4336 0); /*single-precision*/
4337 }
4338 else {
4339 /*HACK!*/
4340 product = *(double*)frA * *(double*)frC;
4341 }
4342 /* compute the subtract */
4343 if (is_invalid_operation(processor, cia,
4344 product, *frB,
4345 fpscr_vxsnan | fpscr_vxisi,
4346 1, /*single?*/
4347 0) /*negate?*/) {
4348 invalid_arithemetic_operation(processor, cia,
4349 frT, product, *frB, 0,
4350 0, /*instruction_is_frsp*/
4351 0, /*instruction_is_convert_to_64bit*/
4352 0, /*instruction_is_convert_to_32bit*/
4353 0); /*single-precision*/
4354 }
4355 else {
4356 /*HACK!*/
4357 float s = -(product - *(double*)frB);
4358 *(double*)frT = (double)s;
4359 }
4360 FPSCR_END(Rc);
4361 ppc_insn_fp3(my_index, processor, cpu_model(processor), frT, frA, frB, frC, Rc);
4362
4363
4364 #
4365 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
4366 #
4367
4368 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4369 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4370 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4371 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4372 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4373 int sign;
4374 int exp;
4375 unsigned64 frac_grx;
4376 /* split off cases for what to do */
4377 if (EXTRACTED64(*frB, 1, 11) < 897
4378 && EXTRACTED64(*frB, 1, 63) > 0) {
4379 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
4380 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
4381 }
4382 if (EXTRACTED64(*frB, 1, 11) > 1150
4383 && EXTRACTED64(*frB, 1, 11) < 2047) {
4384 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4385 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
4386 }
4387 if (EXTRACTED64(*frB, 1, 11) > 896
4388 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
4389 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
4390 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4391 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
4392 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
4393 if (EXTRACTED64(*frB, 12, 12) == 0
4394 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
4395 }
4396 /* handle them */
4397 Disabled_Exponent_Underflow:
4398 sign = EXTRACTED64(*frB, 0, 0);
4399 if (EXTRACTED64(*frB, 1, 11) == 0) {
4400 exp = -1022;
4401 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4402 }
4403 if (EXTRACTED64(*frB, 1, 11) > 0) {
4404 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4405 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4406 }
4407 Denormalize_Operand:
4408 /* G|R|X == zero from above */
4409 while (exp < -126) {
4410 exp = exp - 1;
4411 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4412 | MASKED64(frac_grx, 55, 55));
4413 }
4414 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4415 Round_Single(processor, sign, &exp, &frac_grx);
4416 FPSCR_SET_XX(FPSCR & fpscr_fi);
4417 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4418 *frT = INSERTED64(sign, 0, 0);
4419 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4420 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4421 }
4422 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4423 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4424 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4425 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4426 }
4427 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4428 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4429 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4430 }
4431 /*Normalize_Operand:*/
4432 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4433 exp = exp - 1;
4434 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4435 }
4436 *frT = (INSERTED64(sign, 0, 0)
4437 | INSERTED64(exp + 1023, 1, 11)
4438 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4439 }
4440 goto Done;
4441 Enabled_Exponent_Underflow:
4442 FPSCR_SET_UX(1);
4443 sign = EXTRACTED64(*frB, 0, 0);
4444 if (EXTRACTED64(*frB, 1, 11) == 0) {
4445 exp = -1022;
4446 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4447 }
4448 if (EXTRACTED64(*frB, 1, 11) > 0) {
4449 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4450 frac_grx = (BIT64(0) |
4451 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4452 }
4453 /*Normalize_Operand:*/
4454 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4455 exp = exp - 1;
4456 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4457 }
4458 Round_Single(processor, sign, &exp, &frac_grx);
4459 FPSCR_SET_XX(FPSCR & fpscr_fi);
4460 exp = exp + 192;
4461 *frT = (INSERTED64(sign, 0, 0)
4462 | INSERTED64(exp + 1023, 1, 11)
4463 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4464 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4465 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4466 goto Done;
4467 Disabled_Exponent_Overflow:
4468 FPSCR_SET_OX(1);
4469 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4470 if (EXTRACTED64(*frB, 0, 0) == 0) {
4471 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4472 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4473 }
4474 if (EXTRACTED64(*frB, 0, 0) == 1) {
4475 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4476 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4477 }
4478 }
4479 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4480 if (EXTRACTED64(*frB, 0, 0) == 0) {
4481 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4482 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4483 }
4484 if (EXTRACTED64(*frB, 0, 0) == 1) {
4485 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4486 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4487 }
4488 }
4489 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4490 if (EXTRACTED64(*frB, 0, 0) == 0) {
4491 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4492 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4493 }
4494 if (EXTRACTED64(*frB, 0, 0) == 1) {
4495 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4496 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4497 }
4498 }
4499 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4500 if (EXTRACTED64(*frB, 0, 0) == 0) {
4501 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4502 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4503 }
4504 if (EXTRACTED64(*frB, 0, 0) == 1) {
4505 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4506 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4507 }
4508 }
4509 /* FPSCR[FR] <- undefined */
4510 FPSCR_SET_FI(1);
4511 FPSCR_SET_XX(1);
4512 goto Done;
4513 Enabled_Exponent_Overflow:
4514 sign = EXTRACTED64(*frB, 0, 0);
4515 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4516 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4517 Round_Single(processor, sign, &exp, &frac_grx);
4518 FPSCR_SET_XX(FPSCR & fpscr_fi);
4519 Enabled_Overflow:
4520 FPSCR_SET_OX(1);
4521 exp = exp - 192;
4522 *frT = (INSERTED64(sign, 0, 0)
4523 | INSERTED64(exp + 1023, 1, 11)
4524 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4525 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4526 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4527 goto Done;
4528 Zero_Operand:
4529 *frT = *frB;
4530 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4531 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4532 FPSCR_SET_FR(0);
4533 FPSCR_SET_FI(0);
4534 goto Done;
4535 Infinity_Operand:
4536 *frT = *frB;
4537 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4538 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4539 FPSCR_SET_FR(0);
4540 FPSCR_SET_FI(0);
4541 goto Done;
4542 QNaN_Operand:
4543 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4544 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4545 FPSCR_SET_FR(0);
4546 FPSCR_SET_FI(0);
4547 goto Done;
4548 SNaN_Operand:
4549 FPSCR_OR_VX(fpscr_vxsnan);
4550 if ((FPSCR & fpscr_ve) == 0) {
4551 *frT = (MASKED64(*frB, 0, 11)
4552 | BIT64(12)
4553 | MASKED64(*frB, 13, 34));
4554 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4555 }
4556 FPSCR_SET_FR(0);
4557 FPSCR_SET_FI(0);
4558 goto Done;
4559 Normal_Operand:
4560 sign = EXTRACTED64(*frB, 0, 0);
4561 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4562 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4563 Round_Single(processor, sign, &exp, &frac_grx);
4564 FPSCR_SET_XX(FPSCR & fpscr_fi);
4565 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4566 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4567 *frT = (INSERTED64(sign, 0, 0)
4568 | INSERTED64(exp + 1023, 1, 11)
4569 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4570 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4571 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4572 goto Done;
4573 Done:
4574 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
4575
4576 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4577
4578 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4579
4580 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4581
4582 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4583 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4584 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4585 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4586 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4587 FPSCR_BEGIN;
4588 convert_to_integer(processor, cia,
4589 frT, *frB,
4590 fpscr_rn_round_towards_zero, 32);
4591 FPSCR_END(Rc);
4592 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
4593
4594 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4595 int sign = EXTRACTED64(*frB, 0, 0);
4596 int exp = 63;
4597 unsigned64 frac = *frB;
4598 if (frac == 0) goto Zero_Operand;
4599 if (sign == 1) frac = ~frac + 1;
4600 while (EXTRACTED64(frac, 0, 0) == 0) {
4601 /*??? do the loop 0 times if (FRB) = max negative integer */
4602 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4603 exp = exp - 1;
4604 }
4605 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4606 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4607 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4608 *frT = (INSERTED64(sign, 0, 0)
4609 | INSERTED64(exp + 1023, 1, 11)
4610 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4611 goto Done;
4612 /**/
4613 Zero_Operand:
4614 FPSCR_SET_FR(0);
4615 FPSCR_SET_FI(0);
4616 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4617 *frT = 0;
4618 goto Done;
4619 /**/
4620 Done:
4621 ppc_insn_fp1(my_index, processor, cpu_model(processor), frT, frB, Rc);
4622
4623 #
4624 # I.4.6.7 Floating-Point Compare Instructions
4625 #
4626
4627 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4628 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4629 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4630 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4631 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4632 FPSCR_BEGIN;
4633 unsigned c;
4634 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4635 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4636 else if (is_less_than(frA, frB))
4637 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4638 else if (is_greater_than(frA, frB))
4639 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4640 else
4641 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4642 FPSCR_SET_FPCC(c);
4643 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4644 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4645 FPSCR_OR_VX(fpscr_vxsnan);
4646 FPSCR_END(0);
4647 ppc_insn_fp2_cr(my_index, processor, cpu_model(processor), BF, frA, frB);
4648
4649 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4650 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4651 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4652 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4653 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4654 FPSCR_BEGIN;
4655 unsigned c;
4656 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4657 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4658 else if (is_less_than(frA, frB))
4659 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4660 else if (is_greater_than(frA, frB))
4661 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4662 else
4663 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4664 FPSCR_SET_FPCC(c);
4665 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4666 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4667 FPSCR_OR_VX(fpscr_vxsnan);
4668 if ((FPSCR & fpscr_ve) == 0)
4669 FPSCR_OR_VX(fpscr_vxvc);
4670 }
4671 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4672 FPSCR_OR_VX(fpscr_vxvc);
4673 }
4674 FPSCR_END(0);
4675 ppc_insn_fp2_cr(my_index, processor, cpu_model(processor), BF, frA, frB);
4676
4677
4678 #
4679 # I.4.6.8 Floating-Point Status and Control Register Instructions
4680 #
4681
4682 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4683
4684 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4685
4686 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4687
4688 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4689
4690 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4691
4692 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4693
4694
4695 #
4696 # I.A.1.1 Floating-Point Store Instruction
4697 #
4698 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4699
4700 #
4701 # I.A.1.2 Floating-Point Arithmetic Instructions
4702 #
4703
4704 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
4705
4706 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4707
4708 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
4709
4710 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4711
4712 #
4713 # I.A.1.3 Floating-Point Select Instruction
4714 #
4715
4716 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4717
4718
4719 #
4720 # II.3.2 Cache Management Instructions
4721 #
4722
4723 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4724 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4725 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4726 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4727 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4728 /* blindly flush all instruction cache entries */
4729 #if WITH_IDECODE_CACHE_SIZE
4730 cpu_flush_icache(processor);
4731 #endif
4732 if (RA == 0)
4733 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4734 else
4735 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4736
4737 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4738 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4739 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4740 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4741 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4742 cpu_synchronize_context(processor);
4743 ppc_insn_int0_noout(my_index, processor, cpu_model(processor));
4744
4745
4746 #
4747 # II.3.2.2 Data Cache Instructions
4748 #
4749
4750 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4751 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4752 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4753 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4754 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4755 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4756 if (RA == 0)
4757 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4758 else
4759 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4760
4761 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4762 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4763 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4764 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4765 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4766 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4767 if (RA == 0)
4768 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4769 else
4770 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4771
4772 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4773 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4774 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4775 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4776 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4777 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4778 if (RA == 0)
4779 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4780 else
4781 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4782
4783 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4784 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4785 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4786 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4787 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4788 TRACE(trace_tbd,("Data Cache Block Store\n"));
4789 if (RA == 0)
4790 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4791 else
4792 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4793
4794 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4795 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4796 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4797 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4798 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4799 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4800 if (RA == 0)
4801 ppc_insn_int1_noout(my_index, processor, cpu_model(processor), rB);
4802 else
4803 ppc_insn_int2_noout(my_index, processor, cpu_model(processor), rA, rB);
4804
4805 #
4806 # II.3.3 Enforce In-order Execution of I/O Instruction
4807 #
4808
4809 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4810 /* Since this model has no instruction overlap
4811 this instruction need do nothing */
4812
4813 #
4814 # II.4.1 Time Base Instructions
4815 #
4816
4817 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4818 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4819 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4820 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4821 int n = (tbr{5:9} << 5) | tbr{0:4};
4822 if (n == 268) {
4823 if (is_64bit_implementation) *rT = TB;
4824 else *rT = EXTRACTED64(TB, 32, 63);
4825 }
4826 else if (n == 269) {
4827 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4828 else *rT = EXTRACTED64(TB, 0, 31);
4829 }
4830 else
4831 program_interrupt(processor, cia,
4832 illegal_instruction_program_interrupt);
4833
4834
4835 #
4836 # III.2.3.1 System Linkage Instructions
4837 #
4838
4839 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4840 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4841 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4842 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4843 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4844 if (IS_PROBLEM_STATE(processor)) {
4845 program_interrupt(processor, cia,
4846 privileged_instruction_program_interrupt);
4847 }
4848 else {
4849 MSR = (MASKED(SRR1, 0, 32)
4850 | MASKED(SRR1, 37, 41)
4851 | MASKED(SRR1, 48, 63));
4852 NIA = MASKED(SRR0, 0, 61);
4853 cpu_synchronize_context(processor);
4854 }
4855
4856 #
4857 # III.3.4.1 Move to/from System Register Instructions
4858 #
4859
4860 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
4861 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
4862 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4863 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4864 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4865 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4866 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4867 if (IS_PROBLEM_STATE(processor))
4868 program_interrupt(processor, cia,
4869 privileged_instruction_program_interrupt);
4870 else
4871 MSR = *rS;
4872
4873 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4874 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4875 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4876 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4877 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4878 if (IS_PROBLEM_STATE(processor))
4879 program_interrupt(processor, cia,
4880 privileged_instruction_program_interrupt);
4881 else
4882 *rT = MSR;
4883
4884
4885 #
4886 # III.4.11.1 Cache Management Instructions
4887 #
4888
4889 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4890 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4891 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4892 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4893 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4894 if (IS_PROBLEM_STATE(processor))
4895 program_interrupt(processor, cia,
4896 privileged_instruction_program_interrupt);
4897 else
4898 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4899
4900 #
4901 # III.4.11.2 Segment Register Manipulation Instructions
4902 #
4903
4904 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4905 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4906 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4907 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4908 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4909 if (IS_PROBLEM_STATE(processor))
4910 program_interrupt(processor, cia,
4911 privileged_instruction_program_interrupt);
4912 else
4913 SEGREG(SR) = *rS;
4914
4915 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4916 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4917 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4918 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4919 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4920 if (IS_PROBLEM_STATE(processor))
4921 program_interrupt(processor, cia,
4922 privileged_instruction_program_interrupt);
4923 else
4924 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4925
4926 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4927 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4928 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4929 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4930 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4931 if (IS_PROBLEM_STATE(processor))
4932 program_interrupt(processor, cia,
4933 privileged_instruction_program_interrupt);
4934 else
4935 *rT = SEGREG(SR);
4936
4937 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4938 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4939 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4940 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4941 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4942 if (IS_PROBLEM_STATE(processor))
4943 program_interrupt(processor, cia,
4944 privileged_instruction_program_interrupt);
4945 else
4946 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4947
4948
4949 #
4950 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4951 #
4952
4953 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4954
4955 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4956
4957 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4958
4959 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4960
4961 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4962
4963
4964 #
4965 # III.A.1.2 External Access Instructions
4966 #
4967
4968 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4969
4970 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
This page took 0.140463 seconds and 5 git commands to generate.