Add determining when we do not have enough writeback slots; Do not do model specific...
[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_MODEL 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_MODEL 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_MODEL 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 # I.2.4.1 Branch Instructions
1413 #
1414 0.18,6.LI,30.AA,31.LK:I:t::Branch
1415 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1416 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1417 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1418 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1419 if (AA) NIA = IEA(EXTS(LI_0b00));
1420 else NIA = IEA(CIA + EXTS(LI_0b00));
1421 if (LK) LR = (spreg)CIA+4;
1422 if (CURRENT_MODEL_ISSUE > 0)
1423 model_branches(cpu_model(processor), 1, -1);
1424
1425 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
1426 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1427 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1428 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1429 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1430 int M, ctr_ok, cond_ok, succeed;
1431 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1432 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1433 if (is_64bit_implementation && is_64bit_mode) M = 0;
1434 else M = 32;
1435 if (!BO{2}) CTR = CTR - 1;
1436 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1437 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
1438 if (ctr_ok && cond_ok) {
1439 if (AA) NIA = IEA(EXTS(BD_0b00));
1440 else NIA = IEA(CIA + EXTS(BD_0b00));
1441 succeed = 1;
1442 }
1443 else
1444 succeed = 0;
1445 if (LK) LR = (spreg)IEA(CIA + 4);
1446 if (CURRENT_MODEL_ISSUE > 0)
1447 model_branches(cpu_model(processor), succeed, BO);
1448 if (! BO{0}) {
1449 int reverse;
1450 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1451 reverse = EXTS(BD_0b00) < 0;
1452 } else { /* branch prediction bit not set */
1453 reverse = EXTS(BD_0b00) >= 0;
1454 }
1455 if (CURRENT_MODEL_ISSUE > 0)
1456 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
1457 }
1458
1459 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
1460 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1461 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1462 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1463 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1464 int M, ctr_ok, cond_ok, succeed;
1465 if (is_64bit_implementation && is_64bit_mode) M = 0;
1466 else M = 32;
1467 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1468 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1469 if (!BO{2}) CTR = CTR - 1;
1470 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1471 cond_ok = BO{0} || (CR{BI} == BO{1});
1472 if (ctr_ok && cond_ok) {
1473 NIA = IEA(LR_0b00);
1474 succeed = 1;
1475 }
1476 else
1477 succeed = 0;
1478 if (LK) LR = (spreg)IEA(CIA + 4);
1479 if (CURRENT_MODEL_ISSUE > 0) {
1480 model_branches(cpu_model(processor), succeed, BO);
1481 if (! BO{0})
1482 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1483 }
1484
1485 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
1486 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1487 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1488 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1489 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1490 int cond_ok, succeed;
1491 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
1492 model_wait_for_cr(cpu_model(processor), BIT32_BI);
1493 cond_ok = BO{0} || (CR{BI} == BO{1});
1494 if (cond_ok) {
1495 NIA = IEA(CTR_0b00);
1496 succeed = 1;
1497 }
1498 else
1499 succeed = 0;
1500 if (LK) LR = (spreg)IEA(CIA + 4);
1501 if (CURRENT_MODEL_ISSUE > 0) {
1502 model_branches(cpu_model(processor), succeed, BO);
1503 if (! BO{0})
1504 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1505 }
1506
1507 #
1508 # I.2.4.2 System Call Instruction
1509 #
1510 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
1511 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1512 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1513 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1514 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
1515 if (CURRENT_MODEL_ISSUE > 0)
1516 model_serialize(my_index, cpu_model(processor));
1517 system_call_interrupt(processor, cia);
1518
1519 #
1520 # I.2.4.3 Condition Register Logical Instructions
1521 #
1522 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
1523 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1524 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1525 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1526 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1527 BLIT32(CR, BT, CR{BA} && CR{BB});
1528 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
1529
1530 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
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.193,31./:XL::crxor:Condition Register XOR
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.225,31./:XL::crnand:Condition Register NAND
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.33,31./:XL::crnor:Condition Register NOR
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.289,31./:XL::creqv:Condition Register Equivalent
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.129,31./:XL::crandc:Condition Register AND with Complement
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.417,31./:XL::crorc:Condition Register OR 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 #
1587 # I.2.4.4 Condition Register Field Instruction
1588 #
1589 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
1590 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1591 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1592 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1593 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1594 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
1595 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
1596
1597
1598 #
1599 # I.3.3.2 Fixed-Point Load Instructions
1600 #
1601
1602 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
1603 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1604 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1605 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1606 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1607 unsigned_word b;
1608 unsigned_word EA;
1609 if (RA == 0) b = 0;
1610 else b = *rA;
1611 EA = b + EXTS(D);
1612 *rT = MEM(unsigned, EA, 1);
1613 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1614
1615
1616 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1617 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1618 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1619 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1620 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1621 unsigned_word b;
1622 unsigned_word EA;
1623 if (RA == 0) b = 0;
1624 else b = *rA;
1625 EA = b + *rB;
1626 *rT = MEM(unsigned, EA, 1);
1627 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1628
1629 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1630 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1631 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1632 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1633 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1634 unsigned_word EA;
1635 if (RA == 0 || RA == RT)
1636 program_interrupt(processor, cia,
1637 illegal_instruction_program_interrupt);
1638 EA = *rA + EXTS(D);
1639 *rT = MEM(unsigned, EA, 1);
1640 *rA = EA;
1641 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1642
1643 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1644 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1645 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1646 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1647 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1648 unsigned_word EA;
1649 if (RA == 0 || RA == RT)
1650 program_interrupt(processor, cia,
1651 illegal_instruction_program_interrupt);
1652 EA = *rA + *rB;
1653 *rT = MEM(unsigned, EA, 1);
1654 *rA = EA;
1655 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1656
1657 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1658 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1659 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1660 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1661 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1662 unsigned_word b;
1663 unsigned_word EA;
1664 if (RA == 0) b = 0;
1665 else b = *rA;
1666 EA = b + EXTS(D);
1667 *rT = MEM(unsigned, EA, 2);
1668 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1669
1670 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1671 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1672 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1673 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1674 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1675 unsigned_word b;
1676 unsigned_word EA;
1677 if (RA == 0) b = 0;
1678 else b = *rA;
1679 EA = b + *rB;
1680 *rT = MEM(unsigned, EA, 2);
1681 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1682
1683 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1684 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1685 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1686 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1687 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1688 unsigned_word EA;
1689 if (RA == 0 || RA == RT)
1690 program_interrupt(processor, cia,
1691 illegal_instruction_program_interrupt);
1692 EA = *rA + EXTS(D);
1693 *rT = MEM(unsigned, EA, 2);
1694 *rA = EA;
1695 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1696
1697 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1698 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1699 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1700 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1701 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1702 unsigned_word EA;
1703 if (RA == 0 || RA == RT)
1704 program_interrupt(processor, cia,
1705 illegal_instruction_program_interrupt);
1706 EA = *rA + *rB;
1707 *rT = MEM(unsigned, EA, 2);
1708 *rA = EA;
1709 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1710
1711 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1712 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1713 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1714 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1715 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1716 unsigned_word b;
1717 unsigned_word EA;
1718 if (RA == 0) b = 0;
1719 else b = *rA;
1720 EA = b + EXTS(D);
1721 *rT = MEM(signed, EA, 2);
1722 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1723
1724 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1725 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1726 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1727 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1728 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1729 unsigned_word b;
1730 unsigned_word EA;
1731 if (RA == 0) b = 0;
1732 else b = *rA;
1733 EA = b + *rB;
1734 *rT = MEM(signed, EA, 2);
1735 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1736
1737 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1738 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1739 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1740 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1741 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1742 unsigned_word EA;
1743 if (RA == 0 || RA == RT)
1744 program_interrupt(processor, cia,
1745 illegal_instruction_program_interrupt);
1746 EA = *rA + EXTS(D);
1747 *rT = MEM(signed, EA, 2);
1748 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1749
1750 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1751 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1752 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1753 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1754 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1755 unsigned_word EA;
1756 if (RA == 0 || RA == RT)
1757 program_interrupt(processor, cia,
1758 illegal_instruction_program_interrupt);
1759 EA = *rA + *rB;
1760 *rT = MEM(signed, EA, 2);
1761 *rA = EA;
1762 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1763
1764 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1765 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1766 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1767 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1768 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1769 unsigned_word b;
1770 unsigned_word EA;
1771 if (RA == 0) b = 0;
1772 else b = *rA;
1773 EA = b + EXTS(D);
1774 *rT = MEM(unsigned, EA, 4);
1775 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
1776
1777 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1778 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1779 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1780 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1781 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1782 unsigned_word b;
1783 unsigned_word EA;
1784 if (RA == 0) b = 0;
1785 else b = *rA;
1786 EA = b + *rB;
1787 *rT = MEM(unsigned, EA, 4);
1788 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
1789
1790 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1791 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1792 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1793 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1794 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1795 unsigned_word EA;
1796 if (RA == 0 || RA == RT)
1797 program_interrupt(processor, cia,
1798 illegal_instruction_program_interrupt);
1799 EA = *rA + EXTS(D);
1800 *rT = MEM(unsigned, EA, 4);
1801 *rA = EA;
1802 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
1803
1804 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1805 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1806 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1807 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1808 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1809 unsigned_word EA;
1810 if (RA == 0 || RA == RT)
1811 program_interrupt(processor, cia,
1812 illegal_instruction_program_interrupt);
1813 EA = *rA + *rB;
1814 *rT = MEM(unsigned, EA, 4);
1815 *rA = EA;
1816 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
1817
1818 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1819 # unsigned_word b;
1820 # unsigned_word EA;
1821 # if (RA == 0) b = 0;
1822 # else b = *rA;
1823 # EA = b + EXTS(DS_0b00);
1824 # *rT = MEM(signed, EA, 4);
1825
1826 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1827 # unsigned_word b;
1828 # unsigned_word EA;
1829 # if (RA == 0) b = 0;
1830 # else b = *rA;
1831 # EA = b + *rB;;
1832 # *rT = MEM(signed, EA, 4);
1833
1834 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1835 # unsigned_word EA;
1836 # if (RA == 0 || RA == RT)
1837 # program_interrupt(processor, cia
1838 # illegal_instruction_program_interrupt);
1839 # EA = *rA + *rB;
1840 # *rT = MEM(signed, EA, 4);
1841 # *rA = EA;
1842
1843 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1844 # unsigned_word b;
1845 # unsigned_word EA;
1846 # if (RA == 0) b = 0;
1847 # else b = *rA;
1848 # EA = b + EXTS(DS_0b00);
1849 # *rT = MEM(unsigned, EA, 8);
1850
1851 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1852 # unsigned_word b;
1853 # unsigned_word EA;
1854 # if (RA == 0) b = 0;
1855 # else b = *rA;
1856 # EA = b + *rB;
1857 # *rT = MEM(unsigned, EA, 8);
1858
1859 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1860 # unsigned_word EA;
1861 # if (RA == 0 || RA == RT)
1862 # program_interrupt(processor, cia
1863 # illegal_instruction_program_interrupt);
1864 # EA = *rA + EXTS(DS_0b00);
1865 # *rT = MEM(unsigned, EA, 8);
1866 # *rA = EA;
1867
1868 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1869 # unsigned_word EA;
1870 # if (RA == 0 || RA == RT)
1871 # program_interrupt(processor, cia
1872 # illegal_instruction_program_interrupt);
1873 # EA = *rA + *rB;
1874 # *rT = MEM(unsigned, EA, 8);
1875 # *rA = EA;
1876
1877
1878
1879 #
1880 # I.3.3.3 Fixed-Point Store Instructions
1881 #
1882
1883 0.38,6.RS,11.RA,16.D:D:::Store Byte
1884 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1885 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1886 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1887 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1888 unsigned_word b;
1889 unsigned_word EA;
1890 if (RA == 0) b = 0;
1891 else b = *rA;
1892 EA = b + EXTS(D);
1893 STORE(EA, 1, *rS);
1894 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1895
1896 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1897 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1898 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1899 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1900 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1901 unsigned_word b;
1902 unsigned_word EA;
1903 if (RA == 0) b = 0;
1904 else b = *rA;
1905 EA = b + *rB;
1906 STORE(EA, 1, *rS);
1907 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1908
1909 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1910 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1911 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1912 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1913 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1914 unsigned_word EA;
1915 if (RA == 0)
1916 program_interrupt(processor, cia,
1917 illegal_instruction_program_interrupt);
1918 EA = *rA + EXTS(D);
1919 STORE(EA, 1, *rS);
1920 *rA = EA;
1921 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1922
1923 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1924 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1925 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1926 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1927 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1928 unsigned_word EA;
1929 if (RA == 0)
1930 program_interrupt(processor, cia,
1931 illegal_instruction_program_interrupt);
1932 EA = *rA + *rB;
1933 STORE(EA, 1, *rS);
1934 *rA = EA;
1935 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1936
1937 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1938 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1939 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1940 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1941 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1942 unsigned_word b;
1943 unsigned_word EA;
1944 if (RA == 0) b = 0;
1945 else b = *rA;
1946 EA = b + EXTS(D);
1947 STORE(EA, 2, *rS);
1948 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
1949
1950 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1951 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1952 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1953 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1954 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1955 unsigned_word b;
1956 unsigned_word EA;
1957 if (RA == 0) b = 0;
1958 else b = *rA;
1959 EA = b + *rB;
1960 STORE(EA, 2, *rS);
1961 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
1962
1963 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1964 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1965 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1966 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1967 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1968 unsigned_word EA;
1969 if (RA == 0)
1970 program_interrupt(processor, cia,
1971 illegal_instruction_program_interrupt);
1972 EA = *rA + EXTS(D);
1973 STORE(EA, 2, *rS);
1974 *rA = EA;
1975 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
1976
1977 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1978 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1979 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1980 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1981 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1982 unsigned_word EA;
1983 if (RA == 0)
1984 program_interrupt(processor, cia,
1985 illegal_instruction_program_interrupt);
1986 EA = *rA + *rB;
1987 STORE(EA, 2, *rS);
1988 *rA = EA;
1989 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
1990
1991 0.36,6.RS,11.RA,16.D:D:::Store Word
1992 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1993 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1994 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1995 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
1996 unsigned_word b;
1997 unsigned_word EA;
1998 if (RA == 0) b = 0;
1999 else b = *rA;
2000 EA = b + EXTS(D);
2001 STORE(EA, 4, *rS);
2002 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
2003
2004 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
2005 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2006 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2007 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2008 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2009 unsigned_word b;
2010 unsigned_word EA;
2011 if (RA == 0) b = 0;
2012 else b = *rA;
2013 EA = b + *rB;
2014 STORE(EA, 4, *rS);
2015 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2016
2017 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
2018 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2019 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2020 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2021 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2022 unsigned_word EA;
2023 if (RA == 0)
2024 program_interrupt(processor, cia,
2025 illegal_instruction_program_interrupt);
2026 EA = *rA + EXTS(D);
2027 STORE(EA, 4, *rS);
2028 *rA = EA;
2029 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
2030
2031 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
2032 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2033 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2034 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2035 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2036 unsigned_word EA;
2037 if (RA == 0)
2038 program_interrupt(processor, cia,
2039 illegal_instruction_program_interrupt);
2040 EA = *rA + *rB;
2041 STORE(EA, 4, *rS);
2042 *rA = EA;
2043 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
2044
2045 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2046 # unsigned_word b;
2047 # unsigned_word EA;
2048 # if (RA == 0) b = 0;
2049 # else b = *rA;
2050 # EA = b + EXTS(DS_0b00);
2051 # STORE(EA, 8, *rS);
2052 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2053 # unsigned_word b;
2054 # unsigned_word EA;
2055 # if (RA == 0) b = 0;
2056 # else b = *rA;
2057 # EA = b + *rB;
2058 # STORE(EA, 8, *rS);
2059 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2060 # unsigned_word EA;
2061 # if (RA == 0)
2062 # program_interrupt(processor, cia
2063 # illegal_instruction_program_interrupt);
2064 # EA = *rA + EXTS(DS_0b00);
2065 # STORE(EA, 8, *rS);
2066 # *rA = EA;
2067 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2068 # unsigned_word EA;
2069 # if (RA == 0)
2070 # program_interrupt(processor, cia
2071 # illegal_instruction_program_interrupt);
2072 # EA = *rA + *rB;
2073 # STORE(EA, 8, *rS);
2074 # *rA = EA;
2075
2076
2077 #
2078 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2079 #
2080
2081 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
2082 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2083 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2084 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2085 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2086 unsigned_word b;
2087 unsigned_word EA;
2088 if (RA == 0) b = 0;
2089 else b = *rA;
2090 EA = b + *rB;
2091 *rT = SWAP_2(MEM(unsigned, EA, 2));
2092 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2093
2094 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
2095 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2096 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2097 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2098 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2099 unsigned_word b;
2100 unsigned_word EA;
2101 if (RA == 0) b = 0;
2102 else b = *rA;
2103 EA = b + *rB;
2104 *rT = SWAP_4(MEM(unsigned, EA, 4));
2105 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2106
2107 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
2108 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2109 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2110 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2111 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2112 unsigned_word b;
2113 unsigned_word EA;
2114 if (RA == 0) b = 0;
2115 else b = *rA;
2116 EA = b + *rB;
2117 STORE(EA, 2, SWAP_2(*rS));
2118 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2119
2120 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
2121 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2122 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2123 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2124 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2125 unsigned_word b;
2126 unsigned_word EA;
2127 if (RA == 0) b = 0;
2128 else b = *rA;
2129 EA = b + *rB;
2130 STORE(EA, 4, SWAP_4(*rS));
2131 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
2132
2133
2134 #
2135 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2136 #
2137
2138 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
2139
2140 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2141
2142
2143 #
2144 # I.3.3.6 Fixed-Point Move Assist Instructions
2145 #
2146
2147 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
2148
2149 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2150
2151 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
2152
2153 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2154
2155
2156 #
2157 # I.3.3.7 Storage Synchronization Instructions
2158 #
2159 # HACK: Rather than monitor addresses looking for a reason
2160 # to cancel a reservation. This code instead keeps
2161 # a copy of the data read from memory. Before performing
2162 # a store, the memory area is checked to see if it has
2163 # been changed.
2164 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2165 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2166 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2167 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2168 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2169 unsigned_word b;
2170 unsigned_word EA;
2171 if (RA == 0) b = 0;
2172 else b = *rA;
2173 EA = b + *rB;
2174 RESERVE = 1;
2175 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2176 RESERVE_DATA = MEM(unsigned, EA, 4);
2177 *rT = RESERVE_DATA;
2178 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2179
2180 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2181 unsigned_word b;
2182 unsigned_word EA;
2183 if (RA == 0) b = 0;
2184 else b = *rA;
2185 EA = b + *rB;
2186 RESERVE = 1;
2187 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2188 RESERVE_DATA = MEM(unsigned, EA, 8);
2189 *rT = RESERVE_DATA;
2190 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2191
2192 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2193 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2194 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2195 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2196 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2197 unsigned_word b;
2198 unsigned_word EA;
2199 if (RA == 0) b = 0;
2200 else b = *rA;
2201 EA = b + *rB;
2202 if (RESERVE) {
2203 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2204 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2205 STORE(EA, 4, *rS);
2206 CR_SET_XER_SO(0, cr_i_zero);
2207 }
2208 else {
2209 /* ment to randomly to store, we never do! */
2210 CR_SET_XER_SO(0, 0);
2211 }
2212 RESERVE = 0;
2213 }
2214 else {
2215 CR_SET_XER_SO(0, 0);
2216 }
2217 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2218
2219 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2220 unsigned_word b;
2221 unsigned_word EA;
2222 if (RA == 0) b = 0;
2223 else b = *rA;
2224 EA = b + *rB;
2225 if (RESERVE) {
2226 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2227 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2228 STORE(EA, 8, *rS);
2229 CR_SET_XER_SO(0, cr_i_zero);
2230 }
2231 else {
2232 /* ment to randomly to store, we never do */
2233 CR_SET_XER_SO(0, 0);
2234 }
2235 RESERVE = 0;
2236 }
2237 else {
2238 CR_SET_XER_SO(0, 0);
2239 }
2240 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2241
2242 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2243 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2244 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2245 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2246 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2247 /* do nothing */
2248
2249
2250 #
2251 # I.3.3.9 Fixed-Point Arithmetic Instructions
2252 #
2253
2254 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
2255 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2256 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2257 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2258 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2259 if (RA_is_0) *rT = EXTS(SI);
2260 else *rT = *rA + EXTS(SI);
2261 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2262
2263 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2264 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2265 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2266 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2267 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2268 if (RA_is_0) *rT = EXTS(SI) << 16;
2269 else *rT = *rA + (EXTS(SI) << 16);
2270 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2271
2272 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
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 ALU_BEGIN(*rA);
2278 ALU_ADD(*rB);
2279 ALU_END(*rT, 0/*CA*/, OE, Rc);
2280 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2281
2282 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
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_IU, 1, 1, 0
2286 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2287 ALU_BEGIN(*rA);
2288 ALU_NOT;
2289 ALU_ADD(*rB);
2290 ALU_ADD(1);
2291 ALU_END(*rT, 0/*CA*/, OE, Rc);
2292 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2293
2294 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2295 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2296 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2297 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2298 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2299 ALU_BEGIN(*rA);
2300 ALU_ADD(EXTS(SI));
2301 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2302 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2303
2304 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
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*/, 1/*Rc*/);
2312 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
2313
2314 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
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_NOT;
2321 ALU_ADD(EXTS(SI));
2322 ALU_ADD(1);
2323 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2324 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2325
2326 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2327 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2328 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2329 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2330 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2331 ALU_BEGIN(*rA);
2332 ALU_ADD(*rB);
2333 ALU_END(*rT, 1/*CA*/, OE, Rc);
2334 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2335
2336 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From 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 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2342 ALU_BEGIN(*rA);
2343 ALU_NOT;
2344 ALU_ADD(*rB);
2345 ALU_ADD(1);
2346 ALU_END(*rT, 1/*CA*/, OE, Rc);
2347 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2348
2349 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2350 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2351 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2352 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2353 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2354 ALU_BEGIN(*rA);
2355 ALU_ADD(*rB);
2356 ALU_ADD_CA;
2357 ALU_END(*rT, 1/*CA*/, OE, Rc);
2358 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2359
2360 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2361 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2362 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2363 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2364 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2365 ALU_BEGIN(*rA);
2366 ALU_NOT;
2367 ALU_ADD(*rB);
2368 ALU_ADD_CA;
2369 ALU_END(*rT, 1/*CA*/, OE, Rc);
2370 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2371
2372 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2373 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2374 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2375 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2376 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2377 # ALU_BEGIN(*rA);
2378 # ALU_ADD_CA;
2379 # ALU_SUB(1);
2380 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2381
2382 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From 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_NOT;
2389 # ALU_ADD_CA;
2390 # ALU_SUB(1);
2391 # ALU_END(*rT, 1/*CA*/, OE, Rc);
2392
2393 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero 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_ADD_CA;
2400 ALU_END(*rT, 1/*CA*/, OE, Rc);
2401 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2402
2403 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2404 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2405 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2406 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2407 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2408 ALU_BEGIN(*rA);
2409 ALU_NOT;
2410 ALU_ADD_CA;
2411 ALU_END(*rT, 1/*CA*/, OE, Rc);
2412 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2413
2414 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2415 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2416 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2417 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2418 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2419 ALU_BEGIN(*rA);
2420 ALU_NOT;
2421 ALU_ADD(1);
2422 ALU_END(*rT,0/*CA*/,OE,Rc);
2423 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2424
2425 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2426 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2427 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2428 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2429 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2430 signed_word prod = *rA * EXTS(SI);
2431 *rT = prod;
2432 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2433
2434 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2435
2436 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2437 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2438 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2439 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2440 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2441 signed64 a = (signed32)(*rA);
2442 signed64 b = (signed32)(*rB);
2443 signed64 prod = a * b;
2444 signed_word t = prod;
2445 *rT = *rA * *rB;
2446 if (t != prod && OE)
2447 XER |= (xer_overflow | xer_summary_overflow);
2448 CR0_COMPARE(t, 0, Rc);
2449 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2450
2451 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2452
2453 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2454 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2455 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2456 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2457 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2458 signed64 a = (signed32)(*rA);
2459 signed64 b = (signed32)(*rB);
2460 signed64 prod = a * b;
2461 signed_word t = EXTRACTED64(prod, 0, 31);
2462 *rT = t;
2463 CR0_COMPARE(t, 0, Rc);
2464 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2465
2466 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2467
2468 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
2469 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2470 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2471 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2472 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2473 unsigned64 a = (unsigned32)(*rA);
2474 unsigned64 b = (unsigned32)(*rB);
2475 unsigned64 prod = a * b;
2476 signed_word t = EXTRACTED64(prod, 0, 31);
2477 *rT = t;
2478 CR0_COMPARE(t, 0, Rc);
2479 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2480
2481 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2482
2483 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2484 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2485 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2486 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2487 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2488 signed64 dividend = (signed32)(*rA);
2489 signed64 divisor = (signed32)(*rB);
2490 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2491 || (dividend == 0x80000000 && divisor == -1)) {
2492 if (OE)
2493 XER |= (xer_overflow | xer_summary_overflow);
2494 CR0_COMPARE(0, 0, Rc);
2495 }
2496 else {
2497 signed64 quotent = dividend / divisor;
2498 *rT = quotent;
2499 CR0_COMPARE((signed_word)quotent, 0, Rc);
2500 }
2501 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2502
2503 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2504
2505 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2506 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2507 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2508 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2509 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2510 unsigned64 dividend = (unsigned32)(*rA);
2511 unsigned64 divisor = (unsigned32)(*rB);
2512 if (divisor == 0) {
2513 if (OE)
2514 XER |= (xer_overflow | xer_summary_overflow);
2515 CR0_COMPARE(0, 0, Rc);
2516 }
2517 else {
2518 unsigned64 quotent = dividend / divisor;
2519 *rT = quotent;
2520 CR0_COMPARE((signed_word)quotent, 0, Rc);
2521 }
2522 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2523
2524
2525 #
2526 # I.3.3.10 Fixed-Point Compare Instructions
2527 #
2528
2529 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2530 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2531 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2532 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2533 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2534 if (!is_64bit_mode && L)
2535 program_interrupt(processor, cia,
2536 illegal_instruction_program_interrupt);
2537 else {
2538 signed_word a;
2539 signed_word b = EXTS(SI);
2540 if (L == 0)
2541 a = EXTENDED(*rA);
2542 else
2543 a = *rA;
2544 CR_COMPARE(BF, a, b);
2545 }
2546 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2547
2548 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2549 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2550 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2551 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2552 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2553 if (!is_64bit_mode && L)
2554 program_interrupt(processor, cia,
2555 illegal_instruction_program_interrupt);
2556 else {
2557 signed_word a;
2558 signed_word b;
2559 if (L == 0) {
2560 a = EXTENDED(*rA);
2561 b = EXTENDED(*rB);
2562 }
2563 else {
2564 a = *rA;
2565 b = *rB;
2566 }
2567 CR_COMPARE(BF, a, b);
2568 }
2569 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2570
2571 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2572 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2573 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2574 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2575 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2576 if (!is_64bit_mode && L)
2577 program_interrupt(processor, cia,
2578 illegal_instruction_program_interrupt);
2579 else {
2580 unsigned_word a;
2581 unsigned_word b = UI;
2582 if (L == 0)
2583 a = MASKED(*rA, 32, 63);
2584 else
2585 a = *rA;
2586 CR_COMPARE(BF, a, b);
2587 }
2588 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2589
2590 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2591 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2592 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2593 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2594 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2595 if (!is_64bit_mode && L)
2596 program_interrupt(processor, cia,
2597 illegal_instruction_program_interrupt);
2598 else {
2599 unsigned_word a;
2600 unsigned_word b;
2601 if (L == 0) {
2602 a = MASKED(*rA, 32, 63);
2603 b = MASKED(*rB, 32, 63);
2604 }
2605 else {
2606 a = *rA;
2607 b = *rB;
2608 }
2609 CR_COMPARE(BF, a, b);
2610 }
2611 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2612
2613
2614 #
2615 # I.3.3.11 Fixed-Point Trap Instructions
2616 #
2617
2618 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2619 if (!is_64bit_mode)
2620 program_interrupt(processor, cia,
2621 illegal_instruction_program_interrupt);
2622 else {
2623 signed_word a = *rA;
2624 signed_word b = EXTS(SI);
2625 if ((a < b && TO{0})
2626 || (a > b && TO{1})
2627 || (a == b && TO{2})
2628 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2629 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2630 )
2631 program_interrupt(processor, cia,
2632 trap_program_interrupt);
2633 }
2634
2635 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2636 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2637 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2638 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2639 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2640 signed_word a = EXTENDED(*rA);
2641 signed_word b = EXTS(SI);
2642 if ((a < b && TO{0})
2643 || (a > b && TO{1})
2644 || (a == b && TO{2})
2645 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2646 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2647 )
2648 program_interrupt(processor, cia,
2649 trap_program_interrupt);
2650
2651 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2652 if (!is_64bit_mode)
2653 program_interrupt(processor, cia,
2654 illegal_instruction_program_interrupt);
2655 else {
2656 signed_word a = *rA;
2657 signed_word b = *rB;
2658 if ((a < b && TO{0})
2659 || (a > b && TO{1})
2660 || (a == b && TO{2})
2661 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2662 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2663 )
2664 program_interrupt(processor, cia,
2665 trap_program_interrupt);
2666 }
2667
2668 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2669 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2670 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2671 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2672 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2673 signed_word a = EXTENDED(*rA);
2674 signed_word b = EXTENDED(*rB);
2675 if (TO == 12 && rA == rB) {
2676 ITRACE(trace_breakpoint, ("breakpoint\n"));
2677 cpu_halt(processor, cia, was_trap, 0);
2678 }
2679 else if ((a < b && TO{0})
2680 || (a > b && TO{1})
2681 || (a == b && TO{2})
2682 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2683 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2684 )
2685 program_interrupt(processor, cia,
2686 trap_program_interrupt);
2687
2688 #
2689 # I.3.3.12 Fixed-Point Logical Instructions
2690 #
2691
2692 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2693 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2694 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2695 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2696 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2697 *rA = *rS & UI;
2698 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2699 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2700
2701 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2702 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2703 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2704 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2705 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2706 *rA = *rS & (UI << 16);
2707 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2708 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2709
2710 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2711 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2712 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2713 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2714 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2715 *rA = *rS | UI;
2716 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2717
2718 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2719 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2720 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2721 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2722 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2723 *rA = *rS | (UI << 16);
2724 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2725
2726 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2727 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2728 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2729 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2730 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2731 *rA = *rS ^ UI;
2732 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2733
2734 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2735 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2736 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2737 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2738 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2739 *rA = *rS ^ (UI << 16);
2740 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2741
2742 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
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 & *rB;
2748 CR0_COMPARE(*rA, 0, Rc);
2749 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2750
2751 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
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 | *rB;
2757 CR0_COMPARE(*rA, 0, Rc);
2758 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2759
2760 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
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 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2768
2769 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
2770 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2771 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2772 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2773 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2774 *rA = ~(*rS & *rB);
2775 CR0_COMPARE(*rA, 0, Rc);
2776 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2777
2778 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
2779 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2780 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2781 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2782 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2783 *rA = ~(*rS | *rB);
2784 CR0_COMPARE(*rA, 0, Rc);
2785 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2786
2787 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
2788 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2789 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2790 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2791 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2792 # *rA = ~(*rS ^ *rB); /* A === B */
2793 # CR0_COMPARE(*rA, 0, Rc);
2794
2795 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
2796 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2797 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2798 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2799 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2800 *rA = *rS & ~*rB;
2801 CR0_COMPARE(*rA, 0, Rc);
2802 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2803
2804 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
2805 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2806 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2807 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2808 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2809 *rA = *rS | ~*rB;
2810 CR0_COMPARE(*rA, 0, Rc);
2811 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2812
2813 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
2814 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2815 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2816 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2817 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2818 *rA = (signed_word)(signed8)*rS;
2819 CR0_COMPARE(*rA, 0, Rc);
2820 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2821
2822 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
2823 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2824 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2825 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2826 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2827 *rA = (signed_word)(signed16)*rS;
2828 CR0_COMPARE(*rA, 0, Rc);
2829 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2830
2831 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2832 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2833 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2834 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2835 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2836 # *rA = (signed_word)(signed32)*rS;
2837 # CR0_COMPARE(*rA, 0, Rc);
2838
2839 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2840 # int count = 0;
2841 # unsigned64 mask = BIT64(0);
2842 # unsigned64 source = *rS;
2843 # while (!(source & mask) && mask != 0) {
2844 # mask >>= 1;
2845 # count++;
2846 # }
2847 # *rA = count;
2848 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2849
2850 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros 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 int count = 0;
2856 unsigned32 mask = BIT32(0);
2857 unsigned32 source = *rS;
2858 while (!(source & mask) && mask != 0) {
2859 mask >>= 1;
2860 count++;
2861 }
2862 *rA = count;
2863 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2864
2865
2866 #
2867 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2868 #
2869
2870 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
2871 # long n = (sh_5 << 4) | sh_0_4;
2872 # unsigned_word r = ROTL64(*rS, n);
2873 # long b = (mb_5 << 4) | mb_0_4;
2874 # unsigned_word m = MASK(b, 63);
2875 # signed_word result = r & m;
2876 # *rA = result;
2877 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2878
2879 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
2880 # long n = (sh_5 << 4) | sh_0_4;
2881 # unsigned_word r = ROTL64(*rS, n);
2882 # long e = (me_5 << 4) | me_0_4;
2883 # unsigned_word m = MASK(0, e);
2884 # signed_word result = r & m;
2885 # *rA = result;
2886 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2887
2888 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
2889 # long n = (sh_5 << 4) | sh_0_4;
2890 # unsigned_word r = ROTL64(*rS, n);
2891 # long b = (mb_5 << 4) | mb_0_4;
2892 # unsigned_word m = MASK(0, (64-n));
2893 # signed_word result = r & m;
2894 # *rA = result;
2895 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2896
2897 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2898 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2899 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2900 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2901 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2902 long n = SH;
2903 unsigned32 s = *rS;
2904 unsigned32 r = ROTL32(s, n);
2905 unsigned32 m = MASK(MB+32, ME+32);
2906 signed_word result = r & m;
2907 *rA = result;
2908 CR0_COMPARE(result, 0, Rc);
2909 ITRACE(trace_alu,
2910 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
2911 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
2912 (unsigned long)result, (unsigned long)CR));
2913 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2914
2915 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2916 # long n = MASKED(*rB, 58, 63);
2917 # unsigned_word r = ROTL64(*rS, n);
2918 # long b = (mb_5 << 4) | mb_0_4;
2919 # unsigned_word m = MASK(b, 63);
2920 # signed_word result = r & m;
2921 # *rA = result;
2922 # CR0_COMPARE(result, 0, Rc);
2923
2924 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2925 # long n = MASKED(*rB, 58, 63);
2926 # unsigned_word r = ROTL64(*rS, n);
2927 # long e = (me_5 << 4) | me_0_4;
2928 # unsigned_word m = MASK(0, e);
2929 # signed_word result = r & m;
2930 # *rA = result;
2931 # CR0_COMPARE(result, 0, Rc);
2932
2933 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2934 # long n = MASKED(*rB, 59, 63);
2935 # unsigned32 r = ROTL32(*rS, 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
2941 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
2942 # long n = (sh_5 << 4) | sh_0_4;
2943 # unsigned_word r = ROTL64(*rS, n);
2944 # long b = (mb_5 << 4) | mb_0_4;
2945 # unsigned_word m = MASK(b, (64-n));
2946 # signed_word result = (r & m) | (*rA & ~m)
2947 # *rA = result;
2948 # CR0_COMPARE(result, 0, Rc);
2949
2950 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2951 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2952 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2953 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2954 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2955 long n = SH;
2956 unsigned32 r = ROTL32(*rS, n);
2957 unsigned32 m = MASK(MB+32, ME+32);
2958 signed_word result = (r & m) | (*rA & ~m);
2959 *rA = result;
2960 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
2961 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
2962 (unsigned long)result));
2963 CR0_COMPARE(result, 0, Rc);
2964 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2965
2966
2967 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2968
2969 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2970 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2971 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2972 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2973 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2974 int n = MASKED(*rB, 59, 63);
2975 unsigned32 source = *rS;
2976 signed_word shifted;
2977 if (n < 32)
2978 shifted = (source << n);
2979 else
2980 shifted = 0;
2981 *rA = shifted;
2982 CR0_COMPARE(shifted, 0, Rc);
2983 ITRACE(trace_alu,
2984 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2985 n, (unsigned long)source, (unsigned long)shifted));
2986 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
2987
2988 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
2989
2990 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
2991 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2992 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2993 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2994 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2995 int n = MASKED(*rB, 59, 63);
2996 unsigned32 source = *rS;
2997 signed_word shifted;
2998 if (n < 32)
2999 shifted = (source >> n);
3000 else
3001 shifted = 0;
3002 *rA = shifted;
3003 CR0_COMPARE(shifted, 0, Rc);
3004 ITRACE(trace_alu, \
3005 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3006 n, (unsigned long)source, (unsigned long)shifted));
3007 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3008
3009 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3010
3011 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3012 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3013 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3014 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3015 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3016 int n = SH;
3017 signed_word r = ROTL32(*rS, /*64*/32-n);
3018 signed_word m = MASK(n+32, 63);
3019 int S = MASKED(*rS, 32, 32);
3020 signed_word shifted = (r & m) | (S ? ~m : 0);
3021 *rA = shifted;
3022 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3023 XER |= xer_carry;
3024 else
3025 XER &= ~xer_carry;
3026 CR0_COMPARE(shifted, 0, Rc);
3027 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3028
3029 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3030
3031 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3032 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3033 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3034 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3035 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3036 int n = MASKED(*rB, 58, 63);
3037 int shift = (n >= 31 ? 31 : n);
3038 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3039 signed32 shifted = source >> shift;
3040 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
3041 *rA = (signed_word)shifted; /* if 64bit will sign extend */
3042 if (source < 0 && (source & mask))
3043 XER |= xer_carry;
3044 else
3045 XER &= ~xer_carry;
3046 CR0_COMPARE(shifted, 0, Rc);
3047 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3048
3049 #
3050 # I.3.3.14 Move to/from System Register Instructions
3051 #
3052
3053 0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3054 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3055 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3056 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3057 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3058 int n = (SPR{5:9} << 5) | SPR{0:4};
3059 if (SPR{0} && IS_PROBLEM_STATE(processor))
3060 program_interrupt(processor, cia,
3061 privileged_instruction_program_interrupt);
3062 else if (!spr_is_valid(n)
3063 || spr_is_readonly(n))
3064 program_interrupt(processor, cia,
3065 illegal_instruction_program_interrupt);
3066 else {
3067 spreg new_val = (spr_length(n) == 64
3068 ? *rS
3069 : MASKED(*rS, 32, 63));
3070 /* HACK - time base registers need to be updated immediatly */
3071 if (WITH_TIME_BASE) {
3072 switch (n) {
3073 case spr_tbu:
3074 cpu_set_time_base(processor,
3075 (MASKED64(cpu_get_time_base(processor), 32, 63)
3076 | INSERTED64(new_val, 0, 31)));
3077 break;
3078 case spr_tbl:
3079 cpu_set_time_base(processor,
3080 (MASKED64(cpu_get_time_base(processor), 0, 31)
3081 | INSERTED64(new_val, 32, 63)));
3082 break;
3083 case spr_dec:
3084 cpu_set_decrementer(processor, new_val);
3085 break;
3086 default:
3087 SPREG(n) = new_val;
3088 break;
3089 }
3090 }
3091 else {
3092 SPREG(n) = new_val;
3093 }
3094 }
3095 PPC_INSN_TO_SPR(RS_BITMASK, n);
3096
3097 0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3098 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3099 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3100 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3101 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3102 int n = (SPR{5:9} << 5) | SPR{0:4};
3103 if (SPR{0} && IS_PROBLEM_STATE(processor))
3104 program_interrupt(processor, cia,
3105 privileged_instruction_program_interrupt);
3106 else if (!spr_is_valid(n))
3107 program_interrupt(processor, cia,
3108 illegal_instruction_program_interrupt);
3109 else {
3110 /* HACK - some SPR's need to get their value extracted specially */
3111 *rT = SPREG(n);
3112 }
3113 PPC_INSN_FROM_SPR(RT_BITMASK, n);
3114
3115 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3116 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3117 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3118 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3119 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3120 if (FXM == 0xff) {
3121 CR = *rS;
3122 }
3123 else {
3124 unsigned_word mask = 0;
3125 unsigned_word f;
3126 for (f = 0; f < 8; f++) {
3127 if (FXM & (0x80 >> f))
3128 mask |= (0xf << 4*(7-f));
3129 }
3130 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3131 }
3132 PPC_INSN_MTCR(RS_BITMASK, FXM);
3133
3134 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3135
3136 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3137 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3138 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3139 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3140 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3141 *rT = (unsigned32)CR;
3142 PPC_INSN_MFCR(RT_BITMASK);
3143
3144 #
3145 # I.4.6.2 Floating-Point Load Instructions
3146 #
3147
3148 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3149 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3150 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3151 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3152 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3153 unsigned_word b;
3154 unsigned_word EA;
3155 if (RA == 0) b = 0;
3156 else b = *rA;
3157 EA = b + EXTS(D);
3158 *frT = DOUBLE(MEM(unsigned, EA, 4));
3159 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3160
3161 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3162 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3163 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3164 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3165 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3166 unsigned_word b;
3167 unsigned_word EA;
3168 if (RA == 0) b = 0;
3169 else b = *rA;
3170 EA = b + *rB;
3171 *frT = DOUBLE(MEM(unsigned, EA, 4));
3172 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3173
3174 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3175 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3176 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3177 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3178 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3179 unsigned_word EA;
3180 if (RA == 0)
3181 program_interrupt(processor, cia,
3182 illegal_instruction_program_interrupt);
3183 EA = *rA + EXTS(D);
3184 *frT = DOUBLE(MEM(unsigned, EA, 4));
3185 *rA = EA;
3186 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3187
3188 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
3189 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3190 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3191 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3192 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3193 unsigned_word EA;
3194 if (RA == 0)
3195 program_interrupt(processor, cia,
3196 illegal_instruction_program_interrupt);
3197 EA = *rA + *rB;
3198 *frT = DOUBLE(MEM(unsigned, EA, 4));
3199 *rA = EA;
3200 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3201
3202 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3203 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3204 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3205 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3206 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3207 unsigned_word b;
3208 unsigned_word EA;
3209 if (RA == 0) b = 0;
3210 else b = *rA;
3211 EA = b + EXTS(D);
3212 *frT = MEM(unsigned, EA, 8);
3213 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3214
3215 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3216 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3217 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3218 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3219 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3220 unsigned_word b;
3221 unsigned_word EA;
3222 if (RA == 0) b = 0;
3223 else b = *rA;
3224 EA = b + *rB;
3225 *frT = MEM(unsigned, EA, 8);
3226 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3227
3228 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3229 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3230 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3231 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3232 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3233 unsigned_word EA;
3234 if (RA == 0)
3235 program_interrupt(processor, cia,
3236 illegal_instruction_program_interrupt);
3237 EA = *rA + EXTS(D);
3238 *frT = MEM(unsigned, EA, 8);
3239 *rA = EA;
3240 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3241
3242 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3243 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3244 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3245 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3246 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3247 unsigned_word EA;
3248 if (RA == 0)
3249 program_interrupt(processor, cia,
3250 illegal_instruction_program_interrupt);
3251 EA = *rA + *rB;
3252 *frT = MEM(unsigned, EA, 8);
3253 *rA = EA;
3254 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3255
3256
3257 #
3258 # I.4.6.3 Floating-Point Store Instructions
3259 #
3260
3261 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3262 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3263 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3264 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3265 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3266 unsigned_word b;
3267 unsigned_word EA;
3268 if (RA == 0) b = 0;
3269 else b = *rA;
3270 EA = b + EXTS(D);
3271 STORE(EA, 4, SINGLE(*frS));
3272 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3273
3274 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3275 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3276 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3277 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3278 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3279 unsigned_word b;
3280 unsigned_word EA;
3281 if (RA == 0) b = 0;
3282 else b = *rA;
3283 EA = b + *rB;
3284 STORE(EA, 4, SINGLE(*frS));
3285 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3286
3287 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3288 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3289 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3290 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3291 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3292 unsigned_word EA;
3293 if (RA == 0)
3294 program_interrupt(processor, cia,
3295 illegal_instruction_program_interrupt);
3296 EA = *rA + EXTS(D);
3297 STORE(EA, 4, SINGLE(*frS));
3298 *rA = EA;
3299 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3300
3301 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3302 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3303 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3304 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3305 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3306 unsigned_word EA;
3307 if (RA == 0)
3308 program_interrupt(processor, cia,
3309 illegal_instruction_program_interrupt);
3310 EA = *rA + *rB;
3311 STORE(EA, 4, SINGLE(*frS));
3312 *rA = EA;
3313 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3314
3315 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3316 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3317 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3318 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3319 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3320 unsigned_word b;
3321 unsigned_word EA;
3322 if (RA == 0) b = 0;
3323 else b = *rA;
3324 EA = b + EXTS(D);
3325 STORE(EA, 8, *frS);
3326 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3327
3328 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3329 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3330 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3331 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3332 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3333 unsigned_word b;
3334 unsigned_word EA;
3335 if (RA == 0) b = 0;
3336 else b = *rA;
3337 EA = b + *rB;
3338 STORE(EA, 8, *frS);
3339 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3340
3341 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3342 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3343 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3344 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3345 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3346 unsigned_word EA;
3347 if (RA == 0)
3348 program_interrupt(processor, cia,
3349 illegal_instruction_program_interrupt);
3350 EA = *rA + EXTS(D);
3351 STORE(EA, 8, *frS);
3352 *rA = EA;
3353 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3354
3355 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3356 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3357 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3358 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3359 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3360 unsigned_word EA;
3361 if (RA == 0)
3362 program_interrupt(processor, cia,
3363 illegal_instruction_program_interrupt);
3364 EA = *rA + *rB;
3365 STORE(EA, 8, *frS);
3366 *rA = EA;
3367 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3368
3369
3370 #
3371 # I.4.6.4 Floating-Point Move Instructions
3372 #
3373
3374 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3375 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3376 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3377 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3378 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3379 *frT = *frB;
3380 CR1_UPDATE(Rc);
3381 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3382
3383 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3384 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3385 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3386 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3387 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3388 *frT = *frB ^ BIT64(0);
3389 CR1_UPDATE(Rc);
3390 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3391
3392 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3393 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3394 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3395 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3396 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3397 *frT = *frB & ~BIT64(0);
3398 CR1_UPDATE(Rc);
3399 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3400
3401 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3402 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3403 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3404 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3405 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3406 *frT = *frB | BIT64(0);
3407 CR1_UPDATE(Rc);
3408 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3409
3410
3411 #
3412 # I.4.6.5 Floating-Point Arithmetic Instructions
3413 #
3414
3415 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3416 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3417 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3418 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3419 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3420 FPSCR_BEGIN;
3421 if (is_invalid_operation(processor, cia,
3422 *frA, *frB,
3423 fpscr_vxsnan | fpscr_vxisi,
3424 0, /*single?*/
3425 0) /*negate?*/) {
3426 invalid_arithemetic_operation(processor, cia,
3427 frT, *frA, *frB, 0,
3428 0, /*instruction_is_frsp*/
3429 0, /*instruction_is_convert_to_64bit*/
3430 0, /*instruction_is_convert_to_32bit*/
3431 0); /*single-precision*/
3432 }
3433 else {
3434 /*HACK!*/
3435 double s = *(double*)frA + *(double*)frB;
3436 *(double*)frT = s;
3437 }
3438 FPSCR_END(Rc);
3439 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3440
3441 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3442 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3443 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3444 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3445 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3446 FPSCR_BEGIN;
3447 if (is_invalid_operation(processor, cia,
3448 *frA, *frB,
3449 fpscr_vxsnan | fpscr_vxisi,
3450 1, /*single?*/
3451 0) /*negate?*/) {
3452 invalid_arithemetic_operation(processor, cia,
3453 frT, *frA, *frB, 0,
3454 0, /*instruction_is_frsp*/
3455 0, /*instruction_is_convert_to_64bit*/
3456 0, /*instruction_is_convert_to_32bit*/
3457 1); /*single-precision*/
3458 }
3459 else {
3460 /*HACK!*/
3461 float s = *(double*)frA + *(double*)frB;
3462 *(double*)frT = s;
3463 }
3464 FPSCR_END(Rc);
3465 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3466
3467 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3468 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3469 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3470 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3471 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3472 FPSCR_BEGIN;
3473 if (is_invalid_operation(processor, cia,
3474 *frA, *frB,
3475 fpscr_vxsnan | fpscr_vxisi,
3476 0, /*single?*/
3477 1) /*negate?*/) {
3478 invalid_arithemetic_operation(processor, cia,
3479 frT, *frA, *frB, 0,
3480 0, /*instruction_is_frsp*/
3481 0, /*instruction_is_convert_to_64bit*/
3482 0, /*instruction_is_convert_to_32bit*/
3483 0); /*single-precision*/
3484 }
3485 else {
3486 /*HACK!*/
3487 double s = *(double*)frA - *(double*)frB;
3488 *(double*)frT = s;
3489 }
3490 FPSCR_END(Rc);
3491 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3492
3493 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3494 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3495 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3496 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3497 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3498 FPSCR_BEGIN;
3499 if (is_invalid_operation(processor, cia,
3500 *frA, *frB,
3501 fpscr_vxsnan | fpscr_vxisi,
3502 1, /*single?*/
3503 1) /*negate?*/) {
3504 invalid_arithemetic_operation(processor, cia,
3505 frT, *frA, *frB, 0,
3506 0, /*instruction_is_frsp*/
3507 0, /*instruction_is_convert_to_64bit*/
3508 0, /*instruction_is_convert_to_32bit*/
3509 1); /*single-precision*/
3510 }
3511 else {
3512 /*HACK!*/
3513 float s = *(double*)frA - *(double*)frB;
3514 *(double*)frT = s;
3515 }
3516 FPSCR_END(Rc);
3517 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3518
3519 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3520 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3521 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3522 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3523 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3524 FPSCR_BEGIN;
3525 if (is_invalid_operation(processor, cia,
3526 *frA, *frC,
3527 fpscr_vxsnan | fpscr_vximz,
3528 0, /*single?*/
3529 0) /*negate?*/) {
3530 invalid_arithemetic_operation(processor, cia,
3531 frT, *frA, 0, *frC,
3532 0, /*instruction_is_frsp*/
3533 0, /*instruction_is_convert_to_64bit*/
3534 0, /*instruction_is_convert_to_32bit*/
3535 0); /*single-precision*/
3536 }
3537 else {
3538 /*HACK!*/
3539 double s = *(double*)frA * *(double*)frC;
3540 *(double*)frT = s;
3541 }
3542 FPSCR_END(Rc);
3543 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3544
3545 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3546 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3547 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3548 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3549 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3550 FPSCR_BEGIN;
3551 if (is_invalid_operation(processor, cia,
3552 *frA, *frC,
3553 fpscr_vxsnan | fpscr_vximz,
3554 1, /*single?*/
3555 0) /*negate?*/) {
3556 invalid_arithemetic_operation(processor, cia,
3557 frT, *frA, 0, *frC,
3558 0, /*instruction_is_frsp*/
3559 0, /*instruction_is_convert_to_64bit*/
3560 0, /*instruction_is_convert_to_32bit*/
3561 1); /*single-precision*/
3562 }
3563 else {
3564 /*HACK!*/
3565 float s = *(double*)frA * *(double*)frC;
3566 *(double*)frT = s;
3567 }
3568 FPSCR_END(Rc);
3569 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3570
3571 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3572 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3573 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3574 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3575 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3576 FPSCR_BEGIN;
3577 if (is_invalid_operation(processor, cia,
3578 *frA, *frB,
3579 fpscr_vxsnan | fpscr_vxzdz,
3580 0, /*single?*/
3581 0) /*negate?*/) {
3582 invalid_arithemetic_operation(processor, cia,
3583 frT, *frA, *frB, 0,
3584 0, /*instruction_is_frsp*/
3585 0, /*instruction_is_convert_to_64bit*/
3586 0, /*instruction_is_convert_to_32bit*/
3587 0); /*single-precision*/
3588 }
3589 else {
3590 /*HACK!*/
3591 double s = *(double*)frA / *(double*)frB;
3592 *(double*)frT = s;
3593 }
3594 FPSCR_END(Rc);
3595 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3596
3597 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3598 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3599 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3600 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3601 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3602 FPSCR_BEGIN;
3603 if (is_invalid_operation(processor, cia,
3604 *frA, *frB,
3605 fpscr_vxsnan | fpscr_vxzdz,
3606 1, /*single?*/
3607 0) /*negate?*/) {
3608 invalid_arithemetic_operation(processor, cia,
3609 frT, *frA, *frB, 0,
3610 0, /*instruction_is_frsp*/
3611 0, /*instruction_is_convert_to_64bit*/
3612 0, /*instruction_is_convert_to_32bit*/
3613 1); /*single-precision*/
3614 }
3615 else {
3616 /*HACK!*/
3617 float s = *(double*)frA / *(double*)frB;
3618 *(double*)frT = s;
3619 }
3620 FPSCR_END(Rc);
3621 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3622
3623 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3624 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3625 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3626 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3627 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3628 FPSCR_BEGIN;
3629 double product; /*HACK! - incorrectly loosing precision ... */
3630 /* compute the multiply */
3631 if (is_invalid_operation(processor, cia,
3632 *frA, *frC,
3633 fpscr_vxsnan | fpscr_vximz,
3634 0, /*single?*/
3635 0) /*negate?*/) {
3636 invalid_arithemetic_operation(processor, cia,
3637 (unsigned64*)&product, *frA, 0, *frC,
3638 0, /*instruction_is_frsp*/
3639 0, /*instruction_is_convert_to_64bit*/
3640 0, /*instruction_is_convert_to_32bit*/
3641 0); /*single-precision*/
3642 }
3643 else {
3644 /*HACK!*/
3645 product = *(double*)frA * *(double*)frC;
3646 }
3647 /* compute the add */
3648 if (is_invalid_operation(processor, cia,
3649 product, *frB,
3650 fpscr_vxsnan | fpscr_vxisi,
3651 0, /*single?*/
3652 0) /*negate?*/) {
3653 invalid_arithemetic_operation(processor, cia,
3654 frT, product, *frB, 0,
3655 0, /*instruction_is_frsp*/
3656 0, /*instruction_is_convert_to_64bit*/
3657 0, /*instruction_is_convert_to_32bit*/
3658 0); /*single-precision*/
3659 }
3660 else {
3661 /*HACK!*/
3662 double s = product + *(double*)frB;
3663 *(double*)frT = s;
3664 }
3665 FPSCR_END(Rc);
3666 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3667
3668 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3669 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3670 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3671 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3672 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3673 FPSCR_BEGIN;
3674 float product; /*HACK! - incorrectly loosing precision ... */
3675 /* compute the multiply */
3676 if (is_invalid_operation(processor, cia,
3677 *frA, *frC,
3678 fpscr_vxsnan | fpscr_vximz,
3679 1, /*single?*/
3680 0) /*negate?*/) {
3681 invalid_arithemetic_operation(processor, cia,
3682 (unsigned64*)&product, *frA, 0, *frC,
3683 0, /*instruction_is_frsp*/
3684 0, /*instruction_is_convert_to_64bit*/
3685 0, /*instruction_is_convert_to_32bit*/
3686 0); /*single-precision*/
3687 }
3688 else {
3689 /*HACK!*/
3690 product = *(double*)frA * *(double*)frC;
3691 }
3692 /* compute the add */
3693 if (is_invalid_operation(processor, cia,
3694 product, *frB,
3695 fpscr_vxsnan | fpscr_vxisi,
3696 1, /*single?*/
3697 0) /*negate?*/) {
3698 invalid_arithemetic_operation(processor, cia,
3699 frT, product, *frB, 0,
3700 0, /*instruction_is_frsp*/
3701 0, /*instruction_is_convert_to_64bit*/
3702 0, /*instruction_is_convert_to_32bit*/
3703 0); /*single-precision*/
3704 }
3705 else {
3706 /*HACK!*/
3707 float s = product + *(double*)frB;
3708 *(double*)frT = (double)s;
3709 }
3710 FPSCR_END(Rc);
3711 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3712
3713 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3714 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3715 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3716 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3717 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3718 FPSCR_BEGIN;
3719 double product; /*HACK! - incorrectly loosing precision ... */
3720 /* compute the multiply */
3721 if (is_invalid_operation(processor, cia,
3722 *frA, *frC,
3723 fpscr_vxsnan | fpscr_vximz,
3724 0, /*single?*/
3725 0) /*negate?*/) {
3726 invalid_arithemetic_operation(processor, cia,
3727 (unsigned64*)&product, *frA, 0, *frC,
3728 0, /*instruction_is_frsp*/
3729 0, /*instruction_is_convert_to_64bit*/
3730 0, /*instruction_is_convert_to_32bit*/
3731 0); /*single-precision*/
3732 }
3733 else {
3734 /*HACK!*/
3735 product = *(double*)frA * *(double*)frC;
3736 }
3737 /* compute the subtract */
3738 if (is_invalid_operation(processor, cia,
3739 product, *frB,
3740 fpscr_vxsnan | fpscr_vxisi,
3741 0, /*single?*/
3742 0) /*negate?*/) {
3743 invalid_arithemetic_operation(processor, cia,
3744 frT, product, *frB, 0,
3745 0, /*instruction_is_frsp*/
3746 0, /*instruction_is_convert_to_64bit*/
3747 0, /*instruction_is_convert_to_32bit*/
3748 0); /*single-precision*/
3749 }
3750 else {
3751 /*HACK!*/
3752 double s = product - *(double*)frB;
3753 *(double*)frT = s;
3754 }
3755 FPSCR_END(Rc);
3756 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3757
3758 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
3759 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3760 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3761 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3762 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3763 FPSCR_BEGIN;
3764 float product; /*HACK! - incorrectly loosing precision ... */
3765 /* compute the multiply */
3766 if (is_invalid_operation(processor, cia,
3767 *frA, *frC,
3768 fpscr_vxsnan | fpscr_vximz,
3769 1, /*single?*/
3770 0) /*negate?*/) {
3771 invalid_arithemetic_operation(processor, cia,
3772 (unsigned64*)&product, *frA, 0, *frC,
3773 0, /*instruction_is_frsp*/
3774 0, /*instruction_is_convert_to_64bit*/
3775 0, /*instruction_is_convert_to_32bit*/
3776 0); /*single-precision*/
3777 }
3778 else {
3779 /*HACK!*/
3780 product = *(double*)frA * *(double*)frC;
3781 }
3782 /* compute the subtract */
3783 if (is_invalid_operation(processor, cia,
3784 product, *frB,
3785 fpscr_vxsnan | fpscr_vxisi,
3786 1, /*single?*/
3787 0) /*negate?*/) {
3788 invalid_arithemetic_operation(processor, cia,
3789 frT, product, *frB, 0,
3790 0, /*instruction_is_frsp*/
3791 0, /*instruction_is_convert_to_64bit*/
3792 0, /*instruction_is_convert_to_32bit*/
3793 0); /*single-precision*/
3794 }
3795 else {
3796 /*HACK!*/
3797 float s = product - *(double*)frB;
3798 *(double*)frT = (double)s;
3799 }
3800 FPSCR_END(Rc);
3801 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3802
3803 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
3804 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3805 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3806 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3807 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3808 FPSCR_BEGIN;
3809 double product; /*HACK! - incorrectly loosing precision ... */
3810 /* compute the multiply */
3811 if (is_invalid_operation(processor, cia,
3812 *frA, *frC,
3813 fpscr_vxsnan | fpscr_vximz,
3814 0, /*single?*/
3815 0) /*negate?*/) {
3816 invalid_arithemetic_operation(processor, cia,
3817 (unsigned64*)&product, *frA, 0, *frC,
3818 0, /*instruction_is_frsp*/
3819 0, /*instruction_is_convert_to_64bit*/
3820 0, /*instruction_is_convert_to_32bit*/
3821 0); /*single-precision*/
3822 }
3823 else {
3824 /*HACK!*/
3825 product = *(double*)frA * *(double*)frC;
3826 }
3827 /* compute the add */
3828 if (is_invalid_operation(processor, cia,
3829 product, *frB,
3830 fpscr_vxsnan | fpscr_vxisi,
3831 0, /*single?*/
3832 0) /*negate?*/) {
3833 invalid_arithemetic_operation(processor, cia,
3834 frT, product, *frB, 0,
3835 0, /*instruction_is_frsp*/
3836 0, /*instruction_is_convert_to_64bit*/
3837 0, /*instruction_is_convert_to_32bit*/
3838 0); /*single-precision*/
3839 }
3840 else {
3841 /*HACK!*/
3842 double s = -(product + *(double*)frB);
3843 *(double*)frT = s;
3844 }
3845 FPSCR_END(Rc);
3846 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3847
3848 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
3849 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3850 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3851 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3852 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3853 FPSCR_BEGIN;
3854 float product; /*HACK! - incorrectly loosing precision ... */
3855 /* compute the multiply */
3856 if (is_invalid_operation(processor, cia,
3857 *frA, *frC,
3858 fpscr_vxsnan | fpscr_vximz,
3859 1, /*single?*/
3860 0) /*negate?*/) {
3861 invalid_arithemetic_operation(processor, cia,
3862 (unsigned64*)&product, *frA, 0, *frC,
3863 0, /*instruction_is_frsp*/
3864 0, /*instruction_is_convert_to_64bit*/
3865 0, /*instruction_is_convert_to_32bit*/
3866 0); /*single-precision*/
3867 }
3868 else {
3869 /*HACK!*/
3870 product = *(double*)frA * *(double*)frC;
3871 }
3872 /* compute the add */
3873 if (is_invalid_operation(processor, cia,
3874 product, *frB,
3875 fpscr_vxsnan | fpscr_vxisi,
3876 1, /*single?*/
3877 0) /*negate?*/) {
3878 invalid_arithemetic_operation(processor, cia,
3879 frT, product, *frB, 0,
3880 0, /*instruction_is_frsp*/
3881 0, /*instruction_is_convert_to_64bit*/
3882 0, /*instruction_is_convert_to_32bit*/
3883 0); /*single-precision*/
3884 }
3885 else {
3886 /*HACK!*/
3887 float s = -(product + *(double*)frB);
3888 *(double*)frT = (double)s;
3889 }
3890 FPSCR_END(Rc);
3891 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3892
3893 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
3894 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3895 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3896 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3897 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3898 FPSCR_BEGIN;
3899 double product; /*HACK! - incorrectly loosing precision ... */
3900 /* compute the multiply */
3901 if (is_invalid_operation(processor, cia,
3902 *frA, *frC,
3903 fpscr_vxsnan | fpscr_vximz,
3904 0, /*single?*/
3905 0) /*negate?*/) {
3906 invalid_arithemetic_operation(processor, cia,
3907 (unsigned64*)&product, *frA, 0, *frC,
3908 0, /*instruction_is_frsp*/
3909 0, /*instruction_is_convert_to_64bit*/
3910 0, /*instruction_is_convert_to_32bit*/
3911 0); /*single-precision*/
3912 }
3913 else {
3914 /*HACK!*/
3915 product = *(double*)frA * *(double*)frC;
3916 }
3917 /* compute the subtract */
3918 if (is_invalid_operation(processor, cia,
3919 product, *frB,
3920 fpscr_vxsnan | fpscr_vxisi,
3921 0, /*single?*/
3922 0) /*negate?*/) {
3923 invalid_arithemetic_operation(processor, cia,
3924 frT, product, *frB, 0,
3925 0, /*instruction_is_frsp*/
3926 0, /*instruction_is_convert_to_64bit*/
3927 0, /*instruction_is_convert_to_32bit*/
3928 0); /*single-precision*/
3929 }
3930 else {
3931 /*HACK!*/
3932 double s = -(product - *(double*)frB);
3933 *(double*)frT = s;
3934 }
3935 FPSCR_END(Rc);
3936 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3937
3938 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
3939 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3940 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3941 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3942 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3943 FPSCR_BEGIN;
3944 float product; /*HACK! - incorrectly loosing precision ... */
3945 /* compute the multiply */
3946 if (is_invalid_operation(processor, cia,
3947 *frA, *frC,
3948 fpscr_vxsnan | fpscr_vximz,
3949 1, /*single?*/
3950 0) /*negate?*/) {
3951 invalid_arithemetic_operation(processor, cia,
3952 (unsigned64*)&product, *frA, 0, *frC,
3953 0, /*instruction_is_frsp*/
3954 0, /*instruction_is_convert_to_64bit*/
3955 0, /*instruction_is_convert_to_32bit*/
3956 0); /*single-precision*/
3957 }
3958 else {
3959 /*HACK!*/
3960 product = *(double*)frA * *(double*)frC;
3961 }
3962 /* compute the subtract */
3963 if (is_invalid_operation(processor, cia,
3964 product, *frB,
3965 fpscr_vxsnan | fpscr_vxisi,
3966 1, /*single?*/
3967 0) /*negate?*/) {
3968 invalid_arithemetic_operation(processor, cia,
3969 frT, product, *frB, 0,
3970 0, /*instruction_is_frsp*/
3971 0, /*instruction_is_convert_to_64bit*/
3972 0, /*instruction_is_convert_to_32bit*/
3973 0); /*single-precision*/
3974 }
3975 else {
3976 /*HACK!*/
3977 float s = -(product - *(double*)frB);
3978 *(double*)frT = (double)s;
3979 }
3980 FPSCR_END(Rc);
3981 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3982
3983
3984 #
3985 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
3986 #
3987
3988 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
3989 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3990 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3991 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3992 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3993 int sign;
3994 int exp;
3995 unsigned64 frac_grx;
3996 /* split off cases for what to do */
3997 if (EXTRACTED64(*frB, 1, 11) < 897
3998 && EXTRACTED64(*frB, 1, 63) > 0) {
3999 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
4000 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
4001 }
4002 if (EXTRACTED64(*frB, 1, 11) > 1150
4003 && EXTRACTED64(*frB, 1, 11) < 2047) {
4004 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4005 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
4006 }
4007 if (EXTRACTED64(*frB, 1, 11) > 896
4008 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
4009 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
4010 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4011 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
4012 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
4013 if (EXTRACTED64(*frB, 12, 12) == 0
4014 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
4015 }
4016 /* handle them */
4017 Disabled_Exponent_Underflow:
4018 sign = EXTRACTED64(*frB, 0, 0);
4019 if (EXTRACTED64(*frB, 1, 11) == 0) {
4020 exp = -1022;
4021 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4022 }
4023 if (EXTRACTED64(*frB, 1, 11) > 0) {
4024 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4025 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4026 }
4027 /* G|R|X == zero from above */
4028 while (exp < -126) {
4029 exp = exp - 1;
4030 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4031 | MASKED64(frac_grx, 55, 55));
4032 }
4033 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4034 Round_Single(processor, sign, &exp, &frac_grx);
4035 FPSCR_SET_XX(FPSCR & fpscr_fi);
4036 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4037 *frT = INSERTED64(sign, 0, 0);
4038 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4039 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4040 }
4041 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4042 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4043 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4044 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4045 }
4046 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4047 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4048 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4049 }
4050 /*Normalize_Operand:*/
4051 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4052 exp = exp - 1;
4053 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4054 }
4055 *frT = (INSERTED64(sign, 0, 0)
4056 | INSERTED64(exp + 1023, 1, 11)
4057 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4058 }
4059 goto Done;
4060 Enabled_Exponent_Underflow:
4061 FPSCR_SET_UX(1);
4062 sign = EXTRACTED64(*frB, 0, 0);
4063 if (EXTRACTED64(*frB, 1, 11) == 0) {
4064 exp = -1022;
4065 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4066 }
4067 if (EXTRACTED64(*frB, 1, 11) > 0) {
4068 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4069 frac_grx = (BIT64(0) |
4070 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4071 }
4072 /*Normalize_Operand:*/
4073 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4074 exp = exp - 1;
4075 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4076 }
4077 Round_Single(processor, sign, &exp, &frac_grx);
4078 FPSCR_SET_XX(FPSCR & fpscr_fi);
4079 exp = exp + 192;
4080 *frT = (INSERTED64(sign, 0, 0)
4081 | INSERTED64(exp + 1023, 1, 11)
4082 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4083 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4084 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4085 goto Done;
4086 Disabled_Exponent_Overflow:
4087 FPSCR_SET_OX(1);
4088 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4089 if (EXTRACTED64(*frB, 0, 0) == 0) {
4090 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4091 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4092 }
4093 if (EXTRACTED64(*frB, 0, 0) == 1) {
4094 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4095 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4096 }
4097 }
4098 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4099 if (EXTRACTED64(*frB, 0, 0) == 0) {
4100 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4101 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4102 }
4103 if (EXTRACTED64(*frB, 0, 0) == 1) {
4104 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4105 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4106 }
4107 }
4108 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4109 if (EXTRACTED64(*frB, 0, 0) == 0) {
4110 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4111 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4112 }
4113 if (EXTRACTED64(*frB, 0, 0) == 1) {
4114 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4115 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4116 }
4117 }
4118 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4119 if (EXTRACTED64(*frB, 0, 0) == 0) {
4120 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4121 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4122 }
4123 if (EXTRACTED64(*frB, 0, 0) == 1) {
4124 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4125 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4126 }
4127 }
4128 /* FPSCR[FR] <- undefined */
4129 FPSCR_SET_FI(1);
4130 FPSCR_SET_XX(1);
4131 goto Done;
4132 Enabled_Exponent_Overflow:
4133 sign = EXTRACTED64(*frB, 0, 0);
4134 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4135 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4136 Round_Single(processor, sign, &exp, &frac_grx);
4137 FPSCR_SET_XX(FPSCR & fpscr_fi);
4138 Enabled_Overflow:
4139 FPSCR_SET_OX(1);
4140 exp = exp - 192;
4141 *frT = (INSERTED64(sign, 0, 0)
4142 | INSERTED64(exp + 1023, 1, 11)
4143 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4144 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4145 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4146 goto Done;
4147 Zero_Operand:
4148 *frT = *frB;
4149 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4150 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4151 FPSCR_SET_FR(0);
4152 FPSCR_SET_FI(0);
4153 goto Done;
4154 Infinity_Operand:
4155 *frT = *frB;
4156 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4157 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4158 FPSCR_SET_FR(0);
4159 FPSCR_SET_FI(0);
4160 goto Done;
4161 QNaN_Operand:
4162 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4163 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4164 FPSCR_SET_FR(0);
4165 FPSCR_SET_FI(0);
4166 goto Done;
4167 SNaN_Operand:
4168 FPSCR_OR_VX(fpscr_vxsnan);
4169 if ((FPSCR & fpscr_ve) == 0) {
4170 *frT = (MASKED64(*frB, 0, 11)
4171 | BIT64(12)
4172 | MASKED64(*frB, 13, 34));
4173 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4174 }
4175 FPSCR_SET_FR(0);
4176 FPSCR_SET_FI(0);
4177 goto Done;
4178 Normal_Operand:
4179 sign = EXTRACTED64(*frB, 0, 0);
4180 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4181 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4182 Round_Single(processor, sign, &exp, &frac_grx);
4183 FPSCR_SET_XX(FPSCR & fpscr_fi);
4184 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4185 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4186 *frT = (INSERTED64(sign, 0, 0)
4187 | INSERTED64(exp + 1023, 1, 11)
4188 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4189 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4190 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4191 goto Done;
4192 Done:
4193 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4194
4195 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4196
4197 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4198
4199 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4200
4201 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4202 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4203 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4204 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4205 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4206 FPSCR_BEGIN;
4207 convert_to_integer(processor, cia,
4208 frT, *frB,
4209 fpscr_rn_round_towards_zero, 32);
4210 FPSCR_END(Rc);
4211 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4212
4213 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4214 int sign = EXTRACTED64(*frB, 0, 0);
4215 int exp = 63;
4216 unsigned64 frac = *frB;
4217 if (frac == 0) goto Zero_Operand;
4218 if (sign == 1) frac = ~frac + 1;
4219 while (EXTRACTED64(frac, 0, 0) == 0) {
4220 /*??? do the loop 0 times if (FRB) = max negative integer */
4221 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4222 exp = exp - 1;
4223 }
4224 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4225 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4226 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4227 *frT = (INSERTED64(sign, 0, 0)
4228 | INSERTED64(exp + 1023, 1, 11)
4229 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4230 goto Done;
4231 /**/
4232 Zero_Operand:
4233 FPSCR_SET_FR(0);
4234 FPSCR_SET_FI(0);
4235 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4236 *frT = 0;
4237 goto Done;
4238 /**/
4239 Done:
4240 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4241
4242 #
4243 # I.4.6.7 Floating-Point Compare Instructions
4244 #
4245
4246 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4247 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4248 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4249 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4250 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4251 FPSCR_BEGIN;
4252 unsigned c;
4253 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4254 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4255 else if (is_less_than(frA, frB))
4256 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4257 else if (is_greater_than(frA, frB))
4258 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4259 else
4260 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4261 FPSCR_SET_FPCC(c);
4262 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4263 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4264 FPSCR_OR_VX(fpscr_vxsnan);
4265 FPSCR_END(0);
4266 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4267
4268 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4269 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4270 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4271 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4272 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4273 FPSCR_BEGIN;
4274 unsigned c;
4275 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4276 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4277 else if (is_less_than(frA, frB))
4278 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4279 else if (is_greater_than(frA, frB))
4280 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4281 else
4282 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4283 FPSCR_SET_FPCC(c);
4284 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4285 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4286 FPSCR_OR_VX(fpscr_vxsnan);
4287 if ((FPSCR & fpscr_ve) == 0)
4288 FPSCR_OR_VX(fpscr_vxvc);
4289 }
4290 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4291 FPSCR_OR_VX(fpscr_vxvc);
4292 }
4293 FPSCR_END(0);
4294 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4295
4296
4297 #
4298 # I.4.6.8 Floating-Point Status and Control Register Instructions
4299 #
4300
4301 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4302
4303 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4304
4305 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
4306
4307 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4308
4309 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4310
4311 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4312
4313
4314 #
4315 # I.A.1.1 Floating-Point Store Instruction
4316 #
4317 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4318
4319 #
4320 # I.A.1.2 Floating-Point Arithmetic Instructions
4321 #
4322
4323 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
4324
4325 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4326
4327 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
4328
4329 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4330
4331 #
4332 # I.A.1.3 Floating-Point Select Instruction
4333 #
4334
4335 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4336
4337
4338 #
4339 # II.3.2 Cache Management Instructions
4340 #
4341
4342 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4343 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4344 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4345 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4346 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4347 /* blindly flush all instruction cache entries */
4348 #if WITH_IDECODE_CACHE_SIZE
4349 cpu_flush_icache(processor);
4350 #endif
4351 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4352
4353 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4354 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4355 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4356 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4357 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4358 cpu_synchronize_context(processor);
4359 PPC_INSN_INT(0, 0, 0);
4360
4361
4362 #
4363 # II.3.2.2 Data Cache Instructions
4364 #
4365
4366 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4367 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4368 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4369 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4370 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4371 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4372 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4373
4374 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4375 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4376 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4377 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4378 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4379 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4380 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4381
4382 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4383 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4384 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4385 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4386 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4387 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4388 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4389
4390 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4391 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4392 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4393 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4394 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4395 TRACE(trace_tbd,("Data Cache Block Store\n"));
4396 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4397
4398 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4399 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4400 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4401 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4402 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4403 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4404 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4405
4406 #
4407 # II.3.3 Enforce In-order Execution of I/O Instruction
4408 #
4409
4410 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4411 /* Since this model has no instruction overlap
4412 this instruction need do nothing */
4413
4414 #
4415 # II.4.1 Time Base Instructions
4416 #
4417
4418 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4419 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4420 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4421 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4422 int n = (tbr{5:9} << 5) | tbr{0:4};
4423 if (n == 268) {
4424 if (is_64bit_implementation) *rT = TB;
4425 else *rT = EXTRACTED64(TB, 32, 63);
4426 }
4427 else if (n == 269) {
4428 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4429 else *rT = EXTRACTED64(TB, 0, 31);
4430 }
4431 else
4432 program_interrupt(processor, cia,
4433 illegal_instruction_program_interrupt);
4434
4435
4436 #
4437 # III.2.3.1 System Linkage Instructions
4438 #
4439
4440 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4441 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4442 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4443 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4444 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4445 if (IS_PROBLEM_STATE(processor)) {
4446 program_interrupt(processor, cia,
4447 privileged_instruction_program_interrupt);
4448 }
4449 else {
4450 MSR = (MASKED(SRR1, 0, 32)
4451 | MASKED(SRR1, 37, 41)
4452 | MASKED(SRR1, 48, 63));
4453 NIA = MASKED(SRR0, 0, 61);
4454 cpu_synchronize_context(processor);
4455 }
4456
4457 #
4458 # III.3.4.1 Move to/from System Register Instructions
4459 #
4460
4461 #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4462 #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
4463 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4464 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4465 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4466 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4467 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4468 if (IS_PROBLEM_STATE(processor))
4469 program_interrupt(processor, cia,
4470 privileged_instruction_program_interrupt);
4471 else
4472 MSR = *rS;
4473
4474 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4475 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4476 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4477 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4478 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4479 if (IS_PROBLEM_STATE(processor))
4480 program_interrupt(processor, cia,
4481 privileged_instruction_program_interrupt);
4482 else
4483 *rT = MSR;
4484
4485
4486 #
4487 # III.4.11.1 Cache Management Instructions
4488 #
4489
4490 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4491 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4492 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4493 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4494 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4495 if (IS_PROBLEM_STATE(processor))
4496 program_interrupt(processor, cia,
4497 privileged_instruction_program_interrupt);
4498 else
4499 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4500
4501 #
4502 # III.4.11.2 Segment Register Manipulation Instructions
4503 #
4504
4505 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4506 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4507 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4508 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4509 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4510 if (IS_PROBLEM_STATE(processor))
4511 program_interrupt(processor, cia,
4512 privileged_instruction_program_interrupt);
4513 else
4514 SEGREG(SR) = *rS;
4515
4516 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4517 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4518 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4519 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4520 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4521 if (IS_PROBLEM_STATE(processor))
4522 program_interrupt(processor, cia,
4523 privileged_instruction_program_interrupt);
4524 else
4525 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4526
4527 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4528 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4529 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4530 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4531 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4532 if (IS_PROBLEM_STATE(processor))
4533 program_interrupt(processor, cia,
4534 privileged_instruction_program_interrupt);
4535 else
4536 *rT = SEGREG(SR);
4537
4538 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4539 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4540 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4541 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4542 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4543 if (IS_PROBLEM_STATE(processor))
4544 program_interrupt(processor, cia,
4545 privileged_instruction_program_interrupt);
4546 else
4547 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4548
4549
4550 #
4551 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4552 #
4553
4554 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4555
4556 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4557
4558 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4559
4560 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4561
4562 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4563
4564
4565 #
4566 # III.A.1.2 External Access Instructions
4567 #
4568
4569 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4570
4571 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
This page took 0.119811 seconds and 5 git commands to generate.