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