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