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