checkpoint ppc simulator
[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 # PowerPC models
69 ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, ppc_insn_bad
70 ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, ppc_insn_bad
71 ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, ppc_insn_bad
72 ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, ppc_insn_bad
73
74 # Flags for model.h
75 ::model-data:::
76 typedef enum _ppc_function_unit {
77 PPC_UNIT_BAD, /* unknown function unit */
78 PPC_UNIT_IU, /* integer unit (601/603 style) */
79 PPC_UNIT_SRU, /* system register unit (601/603 style) */
80 PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */
81 PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */
82 PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */
83 PPC_UNIT_FPU, /* floating point unit */
84 PPC_UNIT_LSU, /* load/store unit */
85 PPC_UNIT_BPU, /* branch unit */
86 nr_ppc_function_units
87 } ppc_function_unit;
88
89 /* Structure to hold timing information on a per instruction basis */
90 struct _model_time {
91 ppc_function_unit first_unit; /* first functional unit this insn could use */
92 ppc_function_unit last_unit; /* last functional unit this insn could use */
93 signed16 issue; /* # cycles before function unit can process other insns */
94 signed16 done; /* # cycles before insn is done */
95 void (*function)(itable_index index, /* function to do actual processing */
96 model_data *model_ptr,
97 unsigned_word cia,
98 idecode_cache *cache_entry,
99 instruction_word instruction,
100 const model_time *const default_time);
101
102 };
103
104 /* Register mappings */
105 #define PPC_INT_REG 0 /* start of integer registers */
106 #define PPC_FLOAT_REG (PPC_INT_REG + 32) /* start of floating point registers */
107 #define PPC_CR_REG (PPC_FLOAT_REG + 32) /* start of CR0 .. CR7 */
108 #define PPC_SPR_REG (PPC_CR_REG + 8) /* start of special purpose registers */
109 #define PPC_FPSCR_REG (PPC_SPR_REG + 1024) /* start of fpscr register */
110 #define NR_PPC_REGS (PPC_FPSCR_REG + 1) /* # of registers to allocate */
111
112 /* Structure for each register to indicate whether it is free or not */
113 typedef struct _model_reg model_reg;
114 struct _model_reg {
115 model_reg *next; /* next register to be released */
116 int in_use; /* non zero if register is used */
117 };
118
119 /* Structure for each functional unit that is busy */
120 typedef struct _model_busy model_busy;
121 struct _model_busy {
122 model_busy *next; /* next function unit */
123 model_reg *reg; /* list of registers to release */
124 ppc_function_unit unit; /* function unit name */
125 signed16 issue; /* # of cycles until unit can accept another insn */
126 signed16 done; /* # of cycles until insn is done */
127 };
128
129 /* Structure to hold the current state information for the simulated CPU model */
130 struct _model_data {
131 cpu *processor; /* point back to processor */
132 const char *name; /* model name */
133 const model_time *timing; /* timing information */
134 model_busy *busy_list; /* list of busy function units */
135 model_busy *free_list; /* list of model_busy structs not in use */
136 model_reg registers[NR_PPC_REGS]; /* register status */
137 unsigned32 busy_mask; /* bitmask of busy function units */
138 count_type nr_cycles; /* # cycles */
139 count_type nr_branches; /* # branches */
140 count_type nr_branches_fallthrough; /* # conditional branches that fell through */
141 count_type nr_branch_predict_trues; /* # branches predicted correctly */
142 count_type nr_branch_predict_falses; /* # branches predicted incorrectly */
143 count_type nr_units[nr_ppc_function_units]; /* function unit counts */
144 };
145
146 STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
147 "unknown functional unit instruction",
148 "integer functional unit instruction",
149 "system register functional unit instruction",
150 "1st single cycle integer functional unit instruction",
151 "2nd single cycle integer functional unit instruction",
152 "multiple cycle integer functional unit instruction",
153 "floating point functional unit instruction",
154 "load/store functional unit instruction",
155 "branch functional unit instruction",
156 };
157
158 # Advance state to next cycle, releasing any registers allocated
159 void::model-internal::model_new_cycle:model_data *model_ptr
160 model_busy *cur_busy = model_ptr->busy_list;
161 model_busy *free_list = model_ptr->free_list;
162 model_busy *next_busy = (model_busy *)0;
163 unsigned32 busy_mask = model_ptr->busy_mask;
164 model_busy *next;
165
166 model_ptr->nr_cycles++;
167 for ( ; cur_busy; cur_busy = next) {
168 next = cur_busy->next;
169 if (--cur_busy->done <= 0) { /* function unit done, release registers */
170 model_reg *reg = cur_busy->reg;
171 TRACE(trace_model,("done, retiring %s\n", ppc_function_unit_name[cur_busy->unit]));
172 while (reg) {
173 TRACE(trace_model,("freeing up reg, address 0x%lx (%d)\n", (long)reg, reg - &model_ptr->registers[0]));
174 reg->in_use = 0;
175 reg = reg->next;
176 }
177 busy_mask &= ~(1 << cur_busy->unit);
178 cur_busy->next = free_list;
179 free_list = cur_busy;
180 }
181 else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
182 TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
183 busy_mask &= ~(1 << cur_busy->unit);
184 cur_busy->next = next_busy;
185 next_busy = cur_busy;
186 }
187 else {
188 TRACE(trace_model,("%s still working, issue = %d, done = %d\n",
189 ppc_function_unit_name[cur_busy->unit],
190 cur_busy->issue,
191 cur_busy->done));
192 cur_busy->next = next_busy;
193 next_busy = cur_busy;
194 }
195 }
196
197 model_ptr->busy_list = next_busy;
198 model_ptr->free_list = free_list;
199 model_ptr->busy_mask = busy_mask;
200
201 # Mark a function unit as busy, return the busy structure so regs can be added to be released
202 model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
203 model_busy *busy;
204
205 TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done));
206
207 if (!model_ptr->free_list) {
208 busy = ZALLOC(model_busy);
209 }
210 else {
211 busy = model_ptr->free_list;
212 model_ptr->free_list = busy->next;
213 busy->reg = (model_reg *)0;
214 }
215 busy->next = model_ptr->busy_list;
216 busy->unit = unit;
217 busy->issue = issue;
218 busy->done = done;
219 model_ptr->busy_list = busy;
220 return busy;
221
222 # Signal an instruction this model doesn't support
223 void::model-internal::ppc_insn_bad:itable_index index, model_data *model_ptr, unsigned_word cia, idecode_cache *cache_entry, instruction_word instruction, const model_time *const default_time
224 program_interrupt(model_ptr->processor, cia,
225 illegal_instruction_program_interrupt);
226
227 # Branch instruction, always end the current cycle
228 void::model-internal::ppc_insn_branch:itable_index index, model_data *model_ptr, unsigned_word cia, idecode_cache *cache_entry, instruction_word instruction, const model_time *const default_time
229 model_ptr->nr_units[PPC_UNIT_BPU]++;
230 model_new_cycle(model_ptr);
231
232 # Generic instruction, right now schedule, but don't worry about data dependencies
233 void::model-internal::ppc_insn_generic:itable_index index, model_data *model_ptr, unsigned_word cia, idecode_cache *cache_entry, instruction_word instruction, const model_time *const default_time
234 ppc_function_unit first_unit = default_time->first_unit;
235 ppc_function_unit last_unit = default_time->last_unit;
236 ppc_function_unit unit;
237
238 for (;;) {
239 unsigned32 busy_mask = model_ptr->busy_mask;
240 for (unit = first_unit; unit <= last_unit; unit++) {
241 if (((1 << unit) & busy_mask) == 0) {
242 (void) model_make_busy(model_ptr, unit,
243 model_ptr->timing[index].issue,
244 model_ptr->timing[index].done);
245
246 model_ptr->busy_mask |= (1 << unit);
247 model_ptr->nr_units[unit]++;
248 return;
249 }
250 }
251 model_new_cycle(model_ptr);
252 }
253
254 model_data *::model-function::model_create:cpu *processor
255 model_data *model_ptr = ZALLOC(model_data);
256 ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
257 model_ptr->name = model_name[CURRENT_MODEL];
258 model_ptr->timing = model_time_mapping[CURRENT_MODEL];
259 model_ptr->processor = processor;
260 model_ptr->nr_cycles = 1;
261 return model_ptr;
262
263 void::model-function::model_init:model_data *model_ptr
264
265 void::model-function::model_halt:model_data *model_ptr
266 /* Let pipeline drain */
267 while (model_ptr->busy_list)
268 model_new_cycle(model_ptr);
269
270 void::model-function::model_issue:itable_index index, model_data *model_ptr, unsigned_word cia, idecode_cache *cache_entry, instruction_word instruction
271 const model_time *const default_time = &model_ptr->timing[(int)index];
272 (*default_time->function)(index, model_ptr, cia, cache_entry, instruction, default_time);
273
274 model_print *::model-function::model_mon_info:model_data *model_ptr
275 model_print *head;
276 model_print *tail;
277 ppc_function_unit i;
278
279 head = tail = ZALLOC(model_print);
280 tail->count = model_ptr->nr_cycles;
281 tail->name = "cycle";
282 tail->suffix_plural = "s";
283 tail->suffix_singular = "";
284
285 if (model_ptr->nr_branches) {
286 tail->next = ZALLOC(model_print);
287 tail = tail->next;
288 tail->count = model_ptr->nr_branches;
289 tail->name = "branch";
290 tail->suffix_plural = "es";
291 tail->suffix_singular = "";
292 }
293
294 if (model_ptr->nr_branches_fallthrough) {
295 tail->next = ZALLOC(model_print);
296 tail = tail->next;
297 tail->count = model_ptr->nr_branches_fallthrough;
298 tail->name = "conditional branch";
299 tail->suffix_plural = "es fell through";
300 tail->suffix_singular = " fell through";
301 }
302
303 if (model_ptr->nr_branch_predict_trues) {
304 tail->next = ZALLOC(model_print);
305 tail = tail->next;
306 tail->count = model_ptr->nr_branch_predict_trues;
307 tail->name = "successful branch prediction";
308 tail->suffix_plural = "s";
309 tail->suffix_singular = "";
310 }
311
312 if (model_ptr->nr_branch_predict_falses) {
313 tail->next = ZALLOC(model_print);
314 tail = tail->next;
315 tail->count = model_ptr->nr_branch_predict_falses;
316 tail->name = "unsuccessful branch prediction";
317 tail->suffix_plural = "s";
318 tail->suffix_singular = "";
319 }
320
321 for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
322 if (model_ptr->nr_units[i]) {
323 tail->next = ZALLOC(model_print);
324 tail = tail->next;
325 tail->count = model_ptr->nr_units[i];
326 tail->name = ppc_function_unit_name[i];
327 tail->suffix_plural = "s";
328 tail->suffix_singular = "";
329 }
330 }
331
332 tail->next = (model_print *)0;
333 return head;
334
335 void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr
336 model_print *next;
337
338 while (ptr) {
339 next = ptr->next;
340 free((void *)ptr);
341 ptr = next;
342 }
343
344 void::model-function::model_branches:model_data *model_ptr, int failed
345 if (failed)
346 model_ptr->nr_branches_fallthrough++;
347 else
348 model_ptr->nr_branches++;
349
350 void::model-function::model_branch_predict:model_data *model_ptr, int success
351 if (success)
352 model_ptr->nr_branch_predict_trues++;
353 else
354 model_ptr->nr_branch_predict_falses++;
355
356 # The following (illegal) instruction is `known' by gen and is
357 # called when ever an illegal instruction is encountered
358 ::internal::illegal
359 program_interrupt(processor, cia,
360 illegal_instruction_program_interrupt);
361 return 0;
362
363
364 # The following (floating point unavailable) instruction is `known' by gen
365 # and is called when ever an a floating point instruction is to be
366 # executed but floating point is make unavailable by the MSR
367 ::internal::floating_point_unavailable
368 floating_point_unavailable_interrupt(processor, cia);
369 return 0;
370
371
372 #
373 # Floating point support functions
374 #
375
376 # Convert 32bit single to 64bit double
377 unsigned64::function::DOUBLE:unsigned32 WORD
378 unsigned64 FRT;
379 if (EXTRACTED32(WORD, 1, 8) > 0
380 && EXTRACTED32(WORD, 1, 8) < 255) {
381 /* normalized operand */
382 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
383 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
384 | INSERTED64(not_word_1_1, 2, 2)
385 | INSERTED64(not_word_1_1, 3, 3)
386 | INSERTED64(not_word_1_1, 4, 4)
387 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
388 }
389 else if (EXTRACTED32(WORD, 1, 8) == 0
390 && EXTRACTED32(WORD, 9, 31) != 0) {
391 /* denormalized operand */
392 int sign = EXTRACTED32(WORD, 0, 0);
393 int exp = -126;
394 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
395 /* normalize the operand */
396 while (MASKED64(frac, 0, 0) == 0) {
397 frac <<= 1;
398 exp -= 1;
399 }
400 FRT = (INSERTED64(sign, 0, 0)
401 | INSERTED64(exp + 1023, 1, 11)
402 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
403 }
404 else if (EXTRACTED32(WORD, 1, 8) == 255
405 || EXTRACTED32(WORD, 1, 31) == 0) {
406 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
407 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
408 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
409 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
410 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
411 }
412 else {
413 error("DOUBLE - unknown case\n");
414 FRT = 0;
415 }
416 return FRT;
417
418 # Convert 64bit single to 32bit double
419 unsigned32::function::SINGLE:unsigned64 FRS
420 unsigned32 WORD;
421 if (EXTRACTED64(FRS, 1, 11) > 896
422 || EXTRACTED64(FRS, 1, 63) == 0) {
423 /* no denormalization required (includes Zero/Infinity/NaN) */
424 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
425 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
426 }
427 else if (874 <= EXTRACTED64(FRS, 1, 11)
428 && EXTRACTED64(FRS, 1, 11) <= 896) {
429 /* denormalization required */
430 int sign = EXTRACTED64(FRS, 0, 0);
431 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
432 unsigned64 frac = (BIT64(0)
433 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
434 /* denormalize the operand */
435 while (exp < -126) {
436 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
437 exp += 1;
438 }
439 WORD = (INSERTED32(sign, 0, 0)
440 | INSERTED32(0x00, 1, 8)
441 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
442 }
443 else {
444 WORD = 0x0; /* ??? */
445 }
446 return WORD;
447
448
449 # round 64bit double to 64bit but single
450 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
451 /* comparisons ignore u bits */
452 unsigned64 out;
453 int inc = 0;
454 int lsb = EXTRACTED64(*frac_grx, 23, 23);
455 int gbit = EXTRACTED64(*frac_grx, 24, 24);
456 int rbit = EXTRACTED64(*frac_grx, 25, 25);
457 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
458 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
459 if (lsb == 1 && gbit == 1) inc = 1;
460 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
461 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
462 }
463 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
464 if (sign == 0 && gbit == 1) inc = 1;
465 if (sign == 0 && rbit == 1) inc = 1;
466 if (sign == 0 && xbit == 1) inc = 1;
467 }
468 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
469 if (sign == 1 && gbit == 1) inc = 1;
470 if (sign == 1 && rbit == 1) inc = 1;
471 if (sign == 1 && xbit == 1) inc = 1;
472 }
473 /* work out addition in low 25 bits of out */
474 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
475 *frac_grx = INSERTED64(out, 0, 23);
476 if (out & BIT64(64 - 23 - 1 - 1)) {
477 *frac_grx = (BIT64(0) |
478 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
479 *exp = *exp + 1;
480 }
481 /* frac_grx[24:52] = 0 already */
482 FPSCR_SET_FR(inc);
483 FPSCR_SET_FI(gbit || rbit || xbit);
484
485
486 #
487 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
488 int inc = 0;
489 if (round_mode == fpscr_rn_round_to_nearest) {
490 if (*frac64 == 1 && gbit == 1) inc = 1;
491 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
492 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
493 }
494 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
495 if (sign == 0 && gbit == 1) inc = 1;
496 if (sign == 0 && rbit == 1) inc = 1;
497 if (sign == 0 && xbit == 1) inc = 1;
498 }
499 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
500 if (sign == 1 && gbit == 1) inc = 1;
501 if (sign == 1 && rbit == 1) inc = 1;
502 if (sign == 1 && xbit == 1) inc = 1;
503 }
504 /* frac[0:64] = frac[0:64} + inc */
505 *frac += (*frac64 && inc ? 1 : 0);
506 *frac64 = (*frac64 + inc) & 0x1;
507 FPSCR_SET_FR(inc);
508 FPSCR_SET_FI(gbit | rbit | xbit);
509
510
511 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
512 int carry_out;
513 int inc = 0;
514 int lsb = EXTRACTED64(*frac, 52, 52);
515 int gbit = EXTRACTED64(*frac, 53, 53);
516 int rbit = EXTRACTED64(*frac, 54, 54);
517 int xbit = EXTRACTED64(*frac, 55, 55);
518 if (round_mode == fpscr_rn_round_to_nearest) {
519 if (lsb == 1 && gbit == 1) inc = 1;
520 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
521 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
522 }
523 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
524 if (sign == 0 && gbit == 1) inc = 1;
525 if (sign == 0 && rbit == 1) inc = 1;
526 if (sign == 0 && xbit == 1) inc = 1;
527 }
528 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
529 if (sign == 1 && gbit == 1) inc = 1;
530 if (sign == 1 && rbit == 1) inc = 1;
531 if (sign == 1 && xbit == 1) inc = 1;
532 }
533 /* frac//carry_out = frac + inc */
534 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
535 carry_out = EXTRACTED64(*frac, 0, 0);
536 *frac <<= 1;
537 if (carry_out == 1) *exp = *exp + 1;
538 FPSCR_SET_FR(inc);
539 FPSCR_SET_FI(gbit | rbit | xbit);
540 FPSCR_SET_XX(FPSCR & fpscr_fi);
541
542
543 # conversion of FP to integer
544 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
545 int i;
546 int exp = 0;
547 unsigned64 frac = 0;
548 int frac64 = 0;
549 int gbit = 0;
550 int rbit = 0;
551 int xbit = 0;
552 int sign = EXTRACTED64(frb, 0, 0);
553 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
554 goto Infinity_Operand;
555 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
556 goto SNaN_Operand;
557 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
558 goto QNaN_Operand;
559 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
560 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
561 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
562 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
563 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
564 frac64 = 0;
565 }
566 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
567 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
568 frac64 = 0;
569 }
570 gbit = 0, rbit = 0, xbit = 0;
571 for (i = 1; i <= 63 - exp; i++) {
572 xbit = rbit | xbit;
573 rbit = gbit;
574 gbit = frac64;
575 frac64 = EXTRACTED64(frac, 63, 63);
576 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
577 }
578 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
579 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
580 frac = ~frac;
581 frac64 ^= 1;
582 frac += (frac64 ? 1 : 0);
583 frac64 = (frac64 + 1) & 0x1;
584 }
585 if (tgt_precision == 32 /* can ignore frac64 in compare */
586 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
587 goto Large_Operand;
588 if (tgt_precision == 64 /* can ignore frac64 in compare */
589 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
590 goto Large_Operand;
591 if (tgt_precision == 32 /* can ignore frac64 in compare */
592 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
593 goto Large_Operand;
594 if (tgt_precision == 64 /* can ignore frac64 in compare */
595 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
596 goto Large_Operand;
597 FPSCR_SET_XX(FPSCR & fpscr_fi);
598 if (tgt_precision == 32)
599 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
600 if (tgt_precision == 64)
601 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
602 /*FPSCR[fprf] = undefined */
603 goto Done;
604 /**/
605 Infinity_Operand:
606 FPSCR_SET_FR(0);
607 FPSCR_SET_FI(0);
608 FPSCR_OR_VX(fpscr_vxcvi);
609 if ((FPSCR & fpscr_ve) == 0) {
610 if (tgt_precision == 32) {
611 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
612 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
613 }
614 else {
615 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
616 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
617 }
618 /* FPSCR[FPRF] = undefined */
619 }
620 goto Done;
621 /**/
622 SNaN_Operand:
623 FPSCR_SET_FR(0);
624 FPSCR_SET_FI(0);
625 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
626 if ((FPSCR & fpscr_ve) == 0) {
627 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
628 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
629 /* FPSCR[fprf] = undefined */
630 }
631 goto Done;
632 /**/
633 QNaN_Operand:
634 FPSCR_SET_FR(0);
635 FPSCR_SET_FI(0);
636 FPSCR_OR_VX(fpscr_vxcvi);
637 if ((FPSCR & fpscr_ve) == 0) {
638 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
639 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
640 /* FPSCR[fprf] = undefined */
641 }
642 goto Done;
643 /**/
644 Large_Operand:
645 FPSCR_SET_FR(0);
646 FPSCR_SET_FI(0);
647 FPSCR_OR_VX(fpscr_vxcvi);
648 if ((FPSCR & fpscr_ve) == 0) {
649 if (tgt_precision == 32) {
650 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
651 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
652 }
653 else {
654 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
655 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
656 }
657 /* FPSCR[fprf] = undefined */
658 }
659 /**/
660 Done:
661
662
663 # extract out raw fields of a FP number
664 int::function::sign:unsigned64 FRS
665 return (MASKED64(FRS, 0, 0)
666 ? -1
667 : 1);
668 int::function::biased_exp:unsigned64 frs, int single
669 if (single)
670 return EXTRACTED64(frs, 1, 8);
671 else
672 return EXTRACTED64(frs, 1, 11);
673 unsigned64::function::fraction:unsigned64 frs, int single
674 if (single)
675 return EXTRACTED64(frs, 9, 31);
676 else
677 return EXTRACTED64(frs, 12, 63);
678
679 # a number?, each of the below return +1 or -1 (based on sign bit)
680 # if true.
681 int::function::is_nor:unsigned64 frs, int single
682 int exp = biased_exp(frs, single);
683 return (exp >= 1
684 && exp <= (single ? 254 : 2046));
685 int::function::is_zero:unsigned64 FRS
686 return (MASKED64(FRS, 1, 63) == 0
687 ? sign(FRS)
688 : 0);
689 int::function::is_den:unsigned64 frs, int single
690 int exp = biased_exp(frs, single);
691 unsigned64 frac = fraction(frs, single);
692 return (exp == 0 && frac != 0
693 ? sign(frs)
694 : 0);
695 int::function::is_inf:unsigned64 frs, int single
696 int exp = biased_exp(frs, single);
697 int frac = fraction(frs, single);
698 return (exp == (single ? 255 : 2047) && frac == 0
699 ? sign(frs)
700 : 0);
701 int::function::is_NaN:unsigned64 frs, int single
702 int exp = biased_exp(frs, single);
703 int frac = fraction(frs, single);
704 return (exp == (single ? 255 : 2047) && frac != 0
705 ? sign(frs)
706 : 0);
707 int::function::is_SNaN:unsigned64 frs, int single
708 return (is_NaN(frs, single)
709 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
710 ? sign(frs)
711 : 0);
712 int::function::is_QNaN:unsigned64 frs, int single
713 return (is_NaN(frs, single) && !is_SNaN(frs, single));
714 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
715 return *(double*)fra < *(double*)frb;
716 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
717 return *(double*)fra > *(double*)frb;
718 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
719 return *(double*)fra == *(double*)frb;
720
721
722 # which quiet nan should become the result
723 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
724 unsigned64 frt = 0;
725 if (is_NaN(fra, single))
726 frt = fra;
727 else if (is_NaN(frb, single))
728 if (instruction_is_frsp)
729 frt = MASKED64(frb, 0, 34);
730 else
731 frt = frb;
732 else if (is_NaN(frc, single))
733 frt = frc;
734 else if (generate_qnan)
735 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
736 else
737 error("select_qnan - default reached\n");
738 return frt;
739
740
741 # detect invalid operation
742 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
743 int fail = 0;
744 if ((check & fpscr_vxsnan)
745 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
746 FPSCR_OR_VX(fpscr_vxsnan);
747 fail = 1;
748 }
749 if ((check & fpscr_vxisi)
750 && (is_inf(fra, single) && is_inf(frb, single))
751 && ((negate && sign(fra) != sign(frb))
752 || (!negate && sign(fra) == sign(frb)))) {
753 /*FIXME: don't handle inf-inf VS inf+-inf */
754 FPSCR_OR_VX(fpscr_vxisi);
755 fail = 1;
756 }
757 if ((check & fpscr_vxidi)
758 && (is_inf(fra, single) && is_inf(frb, single))) {
759 FPSCR_OR_VX(fpscr_vxidi);
760 fail = 1;
761 }
762 if ((check & fpscr_vxzdz)
763 && (is_zero(fra) && is_zero(frb))) {
764 FPSCR_OR_VX(fpscr_vxzdz);
765 fail = 1;
766 }
767 if ((check & fpscr_vximz)
768 && (is_zero(fra) && is_inf(frb, single))) {
769 FPSCR_OR_VX(fpscr_vximz);
770 fail = 1;
771 }
772 if ((check & fpscr_vxvc)
773 && (is_NaN(fra, single) || is_NaN(frb, single))) {
774 FPSCR_OR_VX(fpscr_vxvc);
775 fail = 1;
776 }
777 if ((check & fpscr_vxsoft)) {
778 FPSCR_OR_VX(fpscr_vxsoft);
779 fail = 1;
780 }
781 if ((check & fpscr_vxsqrt)
782 && sign(fra) < 0) {
783 FPSCR_OR_VX(fpscr_vxsqrt);
784 fail = 1;
785 }
786 /* if ((check && fpscr_vxcvi) {
787 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
788 FPSCR_OR_VX(fpscr_vxcvi);
789 fail = 1;
790 }
791 */
792 return fail;
793
794
795
796
797
798 # handle case of invalid operation
799 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
800 if (FPSCR & fpscr_ve) {
801 /* invalid operation exception enabled */
802 /* FRT unchaged */
803 FPSCR_SET_FR(0);
804 FPSCR_SET_FI(0);
805 /* fpscr_FPRF unchanged */
806 }
807 else {
808 /* invalid operation exception disabled */
809 if (instruction_is_convert_to_64bit) {
810 error("oopsi");
811 }
812 else if (instruction_is_convert_to_32bit) {
813 error("oopsi");
814 }
815 else { /* arrith, frsp */
816 *frt = select_qnan(fra, frb, frc,
817 instruction_is_frsp, 0/*generate*/, single);
818 FPSCR_SET_FR(0);
819 FPSCR_SET_FI(0);
820 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
821 }
822 }
823
824
825
826
827 #
828 # I.2.4.1 Branch Instructions
829 #
830 0.18,6.LI,30.AA,31.LK:I:t::Branch
831 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
832 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
833 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
834 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
835 if (AA) NIA = IEA(EXTS(LI_0b00));
836 else NIA = IEA(CIA + EXTS(LI_0b00));
837 if (LK) LR = (spreg)CIA+4;
838 model_branches(cpu_model(processor), 1);
839
840 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
841 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
842 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
843 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
844 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
845 int M, ctr_ok, cond_ok, succeed;
846 if (is_64bit_implementation && is_64bit_mode) M = 0;
847 else M = 32;
848 if (!BO{2}) CTR = CTR - 1;
849 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
850 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
851 if (ctr_ok && cond_ok) {
852 if (AA) NIA = IEA(EXTS(BD_0b00));
853 else NIA = IEA(CIA + EXTS(BD_0b00));
854 succeed = 1;
855 }
856 else
857 succeed = 0;
858 if (LK) LR = (spreg)IEA(CIA + 4);
859 model_branches(cpu_model(processor), succeed);
860 if (! BO{0}) {
861 int reverse;
862 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
863 reverse = EXTS(BD_0b00) < 0;
864 } else { /* branch prediction bit not set */
865 reverse = EXTS(BD_0b00) >= 0;
866 }
867 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
868 }
869
870 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
871 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
872 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
873 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
874 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
875 int M, ctr_ok, cond_ok, succeed;
876 if (is_64bit_implementation && is_64bit_mode) M = 0;
877 else M = 32;
878 if (!BO{2}) CTR = CTR - 1;
879 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
880 cond_ok = BO{0} || (CR{BI} == BO{1});
881 if (ctr_ok && cond_ok) {
882 NIA = IEA(LR_0b00);
883 succeed = 1;
884 }
885 else
886 succeed = 0;
887 if (LK) LR = (spreg)IEA(CIA + 4);
888 model_branches(cpu_model(processor), succeed);
889 if (! BO{0})
890 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
891
892 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
893 *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
894 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
895 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
896 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_branch
897 int cond_ok, succeed;
898 cond_ok = BO{0} || (CR{BI} == BO{1});
899 if (cond_ok) {
900 NIA = IEA(CTR_0b00);
901 succeed = 1;
902 }
903 else
904 succeed = 0;
905 if (LK) LR = (spreg)IEA(CIA + 4);
906 model_branches(cpu_model(processor), succeed);
907 if (! BO{0})
908 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
909
910 #
911 # I.2.4.2 System Call Instruction
912 #
913 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
914 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
915 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
916 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
917 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
918 system_call_interrupt(processor, cia);
919
920 #
921 # I.2.4.3 Condition Register Logical Instructions
922 #
923 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
924 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
925 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
926 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
927 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
928 BLIT32(CR, BT, CR{BA} && CR{BB});
929
930 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
931 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
932 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
933 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
934 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
935 BLIT32(CR, BT, CR{BA} || CR{BB});
936
937 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
938 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
939 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
940 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
941 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
942 BLIT32(CR, BT, CR{BA} != CR{BB});
943
944 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
945 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
946 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
947 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
948 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
949 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
950
951 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
952 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
953 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
954 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
955 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
956 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
957
958 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
959 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
960 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
961 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
962 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
963 BLIT32(CR, BT, CR{BA} == CR{BB});
964
965 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
966 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
967 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
968 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
969 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
970 BLIT32(CR, BT, CR{BA} && !CR{BB});
971
972 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
973 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
974 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
975 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
976 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
977 BLIT32(CR, BT, CR{BA} || !CR{BB});
978
979 #
980 # I.2.4.4 Condition Register Field Instruction
981 #
982 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
983 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
984 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
985 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
986 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, ppc_insn_generic
987 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
988
989
990 #
991 # I.3.3.2 Fixed-Point Load Instructions
992 #
993
994 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
995 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
996 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
997 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
998 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
999 unsigned_word b;
1000 unsigned_word EA;
1001 if (RA == 0) b = 0;
1002 else b = *rA;
1003 EA = b + EXTS(D);
1004 *rT = MEM(unsigned, EA, 1);
1005
1006 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
1007 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1008 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1009 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1010 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1011 unsigned_word b;
1012 unsigned_word EA;
1013 if (RA == 0) b = 0;
1014 else b = *rA;
1015 EA = b + *rB;
1016 *rT = MEM(unsigned, EA, 1);
1017
1018 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
1019 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1020 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1021 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1022 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1023 unsigned_word EA;
1024 if (RA == 0 || RA == RT)
1025 program_interrupt(processor, cia,
1026 illegal_instruction_program_interrupt);
1027 EA = *rA + EXTS(D);
1028 *rT = MEM(unsigned, EA, 1);
1029 *rA = EA;
1030
1031 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
1032 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1033 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1034 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1035 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1036 unsigned_word EA;
1037 if (RA == 0 || RA == RT)
1038 program_interrupt(processor, cia,
1039 illegal_instruction_program_interrupt);
1040 EA = *rA + *rB;
1041 *rT = MEM(unsigned, EA, 1);
1042 *rA = EA;
1043
1044 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
1045 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1046 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1047 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1048 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1049 unsigned_word b;
1050 unsigned_word EA;
1051 if (RA == 0) b = 0;
1052 else b = *rA;
1053 EA = b + EXTS(D);
1054 *rT = MEM(unsigned, EA, 2);
1055
1056 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
1057 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1058 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1059 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1060 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1061 unsigned_word b;
1062 unsigned_word EA;
1063 if (RA == 0) b = 0;
1064 else b = *rA;
1065 EA = b + *rB;
1066 *rT = MEM(unsigned, EA, 2);
1067 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
1068 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1069 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1070 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1071 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1072 unsigned_word EA;
1073 if (RA == 0 || RA == RT)
1074 program_interrupt(processor, cia,
1075 illegal_instruction_program_interrupt);
1076 EA = *rA + EXTS(D);
1077 *rT = MEM(unsigned, EA, 2);
1078 *rA = EA;
1079
1080 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
1081 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1082 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1083 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1084 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1085 unsigned_word EA;
1086 if (RA == 0 || RA == RT)
1087 program_interrupt(processor, cia,
1088 illegal_instruction_program_interrupt);
1089 EA = *rA + *rB;
1090 *rT = MEM(unsigned, EA, 2);
1091 *rA = EA;
1092
1093 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
1094 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1095 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1096 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1097 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1098 unsigned_word b;
1099 unsigned_word EA;
1100 if (RA == 0) b = 0;
1101 else b = *rA;
1102 EA = b + EXTS(D);
1103 *rT = MEM(signed, EA, 2);
1104
1105 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
1106 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1107 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1108 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1109 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1110 unsigned_word b;
1111 unsigned_word EA;
1112 if (RA == 0) b = 0;
1113 else b = *rA;
1114 EA = b + *rB;
1115 *rT = MEM(signed, EA, 2);
1116
1117 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
1118 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1119 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1120 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1121 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1122 unsigned_word EA;
1123 if (RA == 0 || RA == RT)
1124 program_interrupt(processor, cia,
1125 illegal_instruction_program_interrupt);
1126 EA = *rA + EXTS(D);
1127 *rT = MEM(signed, EA, 2);
1128
1129 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
1130 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1131 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1132 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1133 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1134 unsigned_word EA;
1135 if (RA == 0 || RA == RT)
1136 program_interrupt(processor, cia,
1137 illegal_instruction_program_interrupt);
1138 EA = *rA + *rB;
1139 *rT = MEM(signed, EA, 2);
1140 *rA = EA;
1141
1142 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
1143 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1144 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1145 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1146 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1147 unsigned_word b;
1148 unsigned_word EA;
1149 if (RA == 0) b = 0;
1150 else b = *rA;
1151 EA = b + EXTS(D);
1152 *rT = MEM(unsigned, EA, 4);
1153
1154 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
1155 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1156 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1157 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1158 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1159 unsigned_word b;
1160 unsigned_word EA;
1161 if (RA == 0) b = 0;
1162 else b = *rA;
1163 EA = b + *rB;
1164 *rT = MEM(unsigned, EA, 4);
1165
1166 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
1167 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1168 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1169 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1170 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1171 unsigned_word EA;
1172 if (RA == 0 || RA == RT)
1173 program_interrupt(processor, cia,
1174 illegal_instruction_program_interrupt);
1175 EA = *rA + EXTS(D);
1176 *rT = MEM(unsigned, EA, 4);
1177 *rA = EA;
1178
1179 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
1180 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1181 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1182 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1183 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1184 unsigned_word EA;
1185 if (RA == 0 || RA == RT)
1186 program_interrupt(processor, cia,
1187 illegal_instruction_program_interrupt);
1188 EA = *rA + *rB;
1189 *rT = MEM(unsigned, EA, 4);
1190 *rA = EA;
1191
1192 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1193 # unsigned_word b;
1194 # unsigned_word EA;
1195 # if (RA == 0) b = 0;
1196 # else b = *rA;
1197 # EA = b + EXTS(DS_0b00);
1198 # *rT = MEM(signed, EA, 4);
1199
1200 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1201 # unsigned_word b;
1202 # unsigned_word EA;
1203 # if (RA == 0) b = 0;
1204 # else b = *rA;
1205 # EA = b + *rB;;
1206 # *rT = MEM(signed, EA, 4);
1207
1208 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1209 # unsigned_word EA;
1210 # if (RA == 0 || RA == RT)
1211 # program_interrupt(processor, cia
1212 # illegal_instruction_program_interrupt);
1213 # EA = *rA + *rB;
1214 # *rT = MEM(signed, EA, 4);
1215 # *rA = EA;
1216
1217 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1218 # unsigned_word b;
1219 # unsigned_word EA;
1220 # if (RA == 0) b = 0;
1221 # else b = *rA;
1222 # EA = b + EXTS(DS_0b00);
1223 # *rT = MEM(unsigned, EA, 8);
1224
1225 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1226 # unsigned_word b;
1227 # unsigned_word EA;
1228 # if (RA == 0) b = 0;
1229 # else b = *rA;
1230 # EA = b + *rB;
1231 # *rT = MEM(unsigned, EA, 8);
1232
1233 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1234 # unsigned_word EA;
1235 # if (RA == 0 || RA == RT)
1236 # program_interrupt(processor, cia
1237 # illegal_instruction_program_interrupt);
1238 # EA = *rA + EXTS(DS_0b00);
1239 # *rT = MEM(unsigned, EA, 8);
1240 # *rA = EA;
1241
1242 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1243 # unsigned_word EA;
1244 # if (RA == 0 || RA == RT)
1245 # program_interrupt(processor, cia
1246 # illegal_instruction_program_interrupt);
1247 # EA = *rA + *rB;
1248 # *rT = MEM(unsigned, EA, 8);
1249 # *rA = EA;
1250
1251
1252
1253 #
1254 # I.3.3.3 Fixed-Point Store Instructions
1255 #
1256
1257 0.38,6.RS,11.RA,16.D:D:::Store Byte
1258 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1259 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1260 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1261 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1262 unsigned_word b;
1263 unsigned_word EA;
1264 if (RA == 0) b = 0;
1265 else b = *rA;
1266 EA = b + EXTS(D);
1267 STORE(EA, 1, *rS);
1268
1269 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
1270 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1271 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1272 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1273 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1274 unsigned_word b;
1275 unsigned_word EA;
1276 if (RA == 0) b = 0;
1277 else b = *rA;
1278 EA = b + *rB;
1279 STORE(EA, 1, *rS);
1280
1281 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
1282 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1283 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1284 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1285 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1286 unsigned_word EA;
1287 if (RA == 0)
1288 program_interrupt(processor, cia,
1289 illegal_instruction_program_interrupt);
1290 EA = *rA + EXTS(D);
1291 STORE(EA, 1, *rS);
1292 *rA = EA;
1293
1294 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
1295 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1296 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1297 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1298 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1299 unsigned_word EA;
1300 if (RA == 0)
1301 program_interrupt(processor, cia,
1302 illegal_instruction_program_interrupt);
1303 EA = *rA + *rB;
1304 STORE(EA, 1, *rS);
1305 *rA = EA;
1306
1307 0.44,6.RS,11.RA,16.D:D:::Store Half Word
1308 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1309 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1310 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1311 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1312 unsigned_word b;
1313 unsigned_word EA;
1314 if (RA == 0) b = 0;
1315 else b = *rA;
1316 EA = b + EXTS(D);
1317 STORE(EA, 2, *rS);
1318
1319 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
1320 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1321 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1322 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1323 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1324 unsigned_word b;
1325 unsigned_word EA;
1326 if (RA == 0) b = 0;
1327 else b = *rA;
1328 EA = b + *rB;
1329 STORE(EA, 2, *rS);
1330
1331 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
1332 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1333 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1334 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1335 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1336 unsigned_word EA;
1337 if (RA == 0)
1338 program_interrupt(processor, cia,
1339 illegal_instruction_program_interrupt);
1340 EA = *rA + EXTS(D);
1341 STORE(EA, 2, *rS);
1342 *rA = EA;
1343
1344 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
1345 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1346 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1347 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1348 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1349 unsigned_word EA;
1350 if (RA == 0)
1351 program_interrupt(processor, cia,
1352 illegal_instruction_program_interrupt);
1353 EA = *rA + *rB;
1354 STORE(EA, 2, *rS);
1355 *rA = EA;
1356
1357 0.36,6.RS,11.RA,16.D:D:::Store Word
1358 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1359 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1360 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1361 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1362 unsigned_word b;
1363 unsigned_word EA;
1364 if (RA == 0) b = 0;
1365 else b = *rA;
1366 EA = b + EXTS(D);
1367 STORE(EA, 4, *rS);
1368
1369 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
1370 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1371 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1372 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1373 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1374 unsigned_word b;
1375 unsigned_word EA;
1376 if (RA == 0) b = 0;
1377 else b = *rA;
1378 EA = b + *rB;
1379 STORE(EA, 4, *rS);
1380
1381 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
1382 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1383 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1384 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1385 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1386 unsigned_word EA;
1387 if (RA == 0)
1388 program_interrupt(processor, cia,
1389 illegal_instruction_program_interrupt);
1390 EA = *rA + EXTS(D);
1391 STORE(EA, 4, *rS);
1392 *rA = EA;
1393
1394 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
1395 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1396 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1397 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1398 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1399 unsigned_word EA;
1400 if (RA == 0)
1401 program_interrupt(processor, cia,
1402 illegal_instruction_program_interrupt);
1403 EA = *rA + *rB;
1404 STORE(EA, 4, *rS);
1405 *rA = EA;
1406
1407 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
1408 # unsigned_word b;
1409 # unsigned_word EA;
1410 # if (RA == 0) b = 0;
1411 # else b = *rA;
1412 # EA = b + EXTS(DS_0b00);
1413 # STORE(EA, 8, *rS);
1414 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
1415 # unsigned_word b;
1416 # unsigned_word EA;
1417 # if (RA == 0) b = 0;
1418 # else b = *rA;
1419 # EA = b + *rB;
1420 # STORE(EA, 8, *rS);
1421 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
1422 # unsigned_word EA;
1423 # if (RA == 0)
1424 # program_interrupt(processor, cia
1425 # illegal_instruction_program_interrupt);
1426 # EA = *rA + EXTS(DS_0b00);
1427 # STORE(EA, 8, *rS);
1428 # *rA = EA;
1429 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
1430 # unsigned_word EA;
1431 # if (RA == 0)
1432 # program_interrupt(processor, cia
1433 # illegal_instruction_program_interrupt);
1434 # EA = *rA + *rB;
1435 # STORE(EA, 8, *rS);
1436 # *rA = EA;
1437
1438
1439 #
1440 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
1441 #
1442
1443 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
1444 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1445 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1446 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1447 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1448 unsigned_word b;
1449 unsigned_word EA;
1450 if (RA == 0) b = 0;
1451 else b = *rA;
1452 EA = b + *rB;
1453 *rT = SWAP_2(MEM(unsigned, EA, 2));
1454
1455 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
1456 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1457 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1458 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1459 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1460 unsigned_word b;
1461 unsigned_word EA;
1462 if (RA == 0) b = 0;
1463 else b = *rA;
1464 EA = b + *rB;
1465 *rT = SWAP_4(MEM(unsigned, EA, 4));
1466
1467 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
1468 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1469 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1470 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1471 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1472 unsigned_word b;
1473 unsigned_word EA;
1474 if (RA == 0) b = 0;
1475 else b = *rA;
1476 EA = b + *rB;
1477 STORE(EA, 2, SWAP_2(*rS));
1478
1479 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
1480 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1481 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1482 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
1483 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1484 unsigned_word b;
1485 unsigned_word EA;
1486 if (RA == 0) b = 0;
1487 else b = *rA;
1488 EA = b + *rB;
1489 STORE(EA, 4, SWAP_4(*rS));
1490
1491
1492 #
1493 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
1494 #
1495
1496 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
1497
1498 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
1499
1500
1501 #
1502 # I.3.3.6 Fixed-Point Move Assist Instructions
1503 #
1504
1505 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
1506
1507 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
1508
1509 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
1510
1511 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
1512
1513
1514 #
1515 # I.3.3.7 Storage Synchronization Instructions
1516 #
1517 # HACK: Rather than monitor addresses looking for a reason
1518 # to cancel a reservation. This code instead keeps
1519 # a copy of the data read from memory. Before performing
1520 # a store, the memory area is checked to see if it has
1521 # been changed.
1522 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
1523 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
1524 *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1525 *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, ppc_insn_generic
1526 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
1527 unsigned_word b;
1528 unsigned_word EA;
1529 if (RA == 0) b = 0;
1530 else b = *rA;
1531 EA = b + *rB;
1532 RESERVE = 1;
1533 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1534 RESERVE_DATA = MEM(unsigned, EA, 4);
1535 *rT = RESERVE_DATA;
1536
1537 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
1538 unsigned_word b;
1539 unsigned_word EA;
1540 if (RA == 0) b = 0;
1541 else b = *rA;
1542 EA = b + *rB;
1543 RESERVE = 1;
1544 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1545 RESERVE_DATA = MEM(unsigned, EA, 8);
1546 *rT = RESERVE_DATA;
1547
1548 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
1549 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1550 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, ppc_insn_generic
1551 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, ppc_insn_generic
1552 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, ppc_insn_generic
1553 unsigned_word b;
1554 unsigned_word EA;
1555 if (RA == 0) b = 0;
1556 else b = *rA;
1557 EA = b + *rB;
1558 if (RESERVE) {
1559 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1560 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
1561 STORE(EA, 4, *rS);
1562 CR_SET_XER_SO(0, cr_i_zero);
1563 }
1564 else {
1565 /* ment to randomly to store, we never do! */
1566 CR_SET_XER_SO(0, 0);
1567 }
1568 RESERVE = 0;
1569 }
1570 else {
1571 CR_SET_XER_SO(0, 0);
1572 }
1573 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
1574 unsigned_word b;
1575 unsigned_word EA;
1576 if (RA == 0) b = 0;
1577 else b = *rA;
1578 EA = b + *rB;
1579 if (RESERVE) {
1580 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1581 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
1582 STORE(EA, 8, *rS);
1583 CR_SET_XER_SO(0, cr_i_zero);
1584 }
1585 else {
1586 /* ment to randomly to store, we never do */
1587 CR_SET_XER_SO(0, 0);
1588 }
1589 RESERVE = 0;
1590 }
1591 else {
1592 CR_SET_XER_SO(0, 0);
1593 }
1594
1595 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
1596 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1597 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1598 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1599 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
1600 /* do nothing */
1601
1602
1603 #
1604 # I.3.3.9 Fixed-Point Arithmetic Instructions
1605 #
1606
1607 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
1608 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1609 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1610 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1611 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1612 if (RA_is_0) *rT = EXTS(SI);
1613 else *rT = *rA + EXTS(SI);
1614
1615 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
1616 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1617 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1618 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1619 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1620 if (RA_is_0) *rT = EXTS(SI) << 16;
1621 else *rT = *rA + (EXTS(SI) << 16);
1622
1623 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
1624 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1625 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1626 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1627 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1628 ALU_BEGIN(*rA);
1629 ALU_ADD(*rB);
1630 ALU_END(*rT, 0/*CA*/, OE, Rc);
1631
1632 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
1633 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1634 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1635 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1636 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1637 ALU_BEGIN(*rA);
1638 ALU_NOT;
1639 ALU_ADD(*rB);
1640 ALU_ADD(1);
1641 ALU_END(*rT, 0/*CA*/, OE, Rc);
1642
1643 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
1644 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1645 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1646 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1647 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1648 ALU_BEGIN(*rA);
1649 ALU_ADD(EXTS(SI));
1650 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1651
1652 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
1653 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1654 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1655 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1656 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1657 ALU_BEGIN(*rA);
1658 ALU_ADD(EXTS(SI));
1659 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
1660
1661 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
1662 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1663 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1664 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1665 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1666 ALU_BEGIN(*rA);
1667 ALU_NOT;
1668 ALU_ADD(EXTS(SI));
1669 ALU_ADD(1);
1670 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1671
1672 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
1673 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1674 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1675 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1676 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1677 ALU_BEGIN(*rA);
1678 ALU_ADD(*rB);
1679 ALU_END(*rT, 1/*CA*/, OE, Rc);
1680
1681 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
1682 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1683 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1684 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1685 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1686 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
1687 ALU_BEGIN(*rA);
1688 ALU_NOT;
1689 ALU_ADD(*rB);
1690 ALU_ADD(1);
1691 ALU_END(*rT, 1/*CA*/, OE, Rc);
1692
1693 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
1694 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1695 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1696 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1697 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1698 ALU_BEGIN(*rA);
1699 ALU_ADD(*rB);
1700 ALU_ADD_CA;
1701 ALU_END(*rT, 1/*CA*/, OE, Rc);
1702
1703 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
1704 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1705 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1706 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1707 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1708 ALU_BEGIN(*rA);
1709 ALU_NOT;
1710 ALU_ADD(*rB);
1711 ALU_ADD_CA;
1712 ALU_END(*rT, 1/*CA*/, OE, Rc);
1713
1714 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
1715 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1716 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1717 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1718 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1719 # ALU_BEGIN(*rA);
1720 # ALU_ADD_CA;
1721 # ALU_SUB(1);
1722 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1723
1724 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
1725 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1726 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1727 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1728 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1729 # ALU_BEGIN(*rA);
1730 # ALU_NOT;
1731 # ALU_ADD_CA;
1732 # ALU_SUB(1);
1733 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1734
1735 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
1736 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1737 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1738 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1739 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1740 ALU_BEGIN(*rA);
1741 ALU_ADD_CA;
1742 ALU_END(*rT, 1/*CA*/, OE, Rc);
1743
1744 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
1745 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1746 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1747 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1748 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1749 ALU_BEGIN(*rA);
1750 ALU_NOT;
1751 ALU_ADD_CA;
1752 ALU_END(*rT, 1/*CA*/, OE, Rc);
1753
1754 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
1755 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1756 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1757 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1758 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1759 ALU_BEGIN(*rA);
1760 ALU_NOT;
1761 ALU_ADD(1);
1762 ALU_END(*rT,0/*CA*/,OE,Rc);
1763
1764 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
1765 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1766 *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
1767 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
1768 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
1769 signed_word prod = *rA * EXTS(SI);
1770 *rT = prod;
1771
1772 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
1773
1774 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
1775 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1776 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1777 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1778 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, ppc_insn_generic
1779 signed64 a = (signed32)(*rA);
1780 signed64 b = (signed32)(*rB);
1781 signed64 prod = a * b;
1782 signed_word t = prod;
1783 *rT = *rA * *rB;
1784 if (t != prod && OE)
1785 XER |= (xer_overflow | xer_summary_overflow);
1786 CR0_COMPARE(t, 0, Rc);
1787
1788 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
1789
1790 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
1791 *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1792 *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1793 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, ppc_insn_generic
1794 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, ppc_insn_generic
1795 signed64 a = (signed32)(*rA);
1796 signed64 b = (signed32)(*rB);
1797 signed64 prod = a * b;
1798 signed_word t = EXTRACTED64(prod, 0, 31);
1799 *rT = t;
1800 CR0_COMPARE(t, 0, Rc);
1801
1802 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
1803
1804 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
1805 *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, ppc_insn_generic
1806 *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, ppc_insn_generic
1807 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, ppc_insn_generic
1808 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, ppc_insn_generic
1809 unsigned64 a = (unsigned32)(*rA);
1810 unsigned64 b = (unsigned32)(*rB);
1811 unsigned64 prod = a * b;
1812 signed_word t = EXTRACTED64(prod, 0, 31);
1813 *rT = t;
1814 CR0_COMPARE(t, 0, Rc);
1815
1816 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
1817
1818 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
1819 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, ppc_insn_generic
1820 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, ppc_insn_generic
1821 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, ppc_insn_generic
1822 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, ppc_insn_generic
1823 signed64 dividend = (signed32)(*rA);
1824 signed64 divisor = (signed32)(*rB);
1825 if (divisor == 0 /* nb 0x8000..0 is sign extended */
1826 || (dividend == 0x80000000 && divisor == -1)) {
1827 if (OE)
1828 XER |= (xer_overflow | xer_summary_overflow);
1829 CR0_COMPARE(0, 0, Rc);
1830 }
1831 else {
1832 signed64 quotent = dividend / divisor;
1833 *rT = quotent;
1834 CR0_COMPARE((signed_word)quotent, 0, Rc);
1835 }
1836 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
1837
1838 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
1839 *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, ppc_insn_generic
1840 *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, ppc_insn_generic
1841 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, ppc_insn_generic
1842 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, ppc_insn_generic
1843 unsigned64 dividend = (unsigned32)(*rA);
1844 unsigned64 divisor = (unsigned32)(*rB);
1845 if (divisor == 0) {
1846 if (OE)
1847 XER |= (xer_overflow | xer_summary_overflow);
1848 CR0_COMPARE(0, 0, Rc);
1849 }
1850 else {
1851 unsigned64 quotent = dividend / divisor;
1852 *rT = quotent;
1853 CR0_COMPARE((signed_word)quotent, 0, Rc);
1854 }
1855
1856
1857 #
1858 # I.3.3.10 Fixed-Point Compare Instructions
1859 #
1860
1861 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
1862 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1863 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1864 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1865 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1866 if (!is_64bit_mode && L)
1867 program_interrupt(processor, cia,
1868 illegal_instruction_program_interrupt);
1869 else {
1870 signed_word a;
1871 signed_word b = EXTS(SI);
1872 if (L == 0)
1873 a = EXTENDED(*rA);
1874 else
1875 a = *rA;
1876 CR_COMPARE(BF, a, b);
1877 }
1878
1879 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
1880 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1881 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1882 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1883 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1884 if (!is_64bit_mode && L)
1885 program_interrupt(processor, cia,
1886 illegal_instruction_program_interrupt);
1887 else {
1888 signed_word a;
1889 signed_word b;
1890 if (L == 0) {
1891 a = EXTENDED(*rA);
1892 b = EXTENDED(*rB);
1893 }
1894 else {
1895 a = *rA;
1896 b = *rB;
1897 }
1898 CR_COMPARE(BF, a, b);
1899 }
1900
1901 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
1902 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1903 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1904 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1905 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1906 if (!is_64bit_mode && L)
1907 program_interrupt(processor, cia,
1908 illegal_instruction_program_interrupt);
1909 else {
1910 unsigned_word a;
1911 unsigned_word b = UI;
1912 if (L == 0)
1913 a = MASKED(*rA, 32, 63);
1914 else
1915 a = *rA;
1916 CR_COMPARE(BF, a, b);
1917 }
1918
1919 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
1920 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1921 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1922 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
1923 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1924 if (!is_64bit_mode && L)
1925 program_interrupt(processor, cia,
1926 illegal_instruction_program_interrupt);
1927 else {
1928 unsigned_word a;
1929 unsigned_word b;
1930 if (L == 0) {
1931 a = MASKED(*rA, 32, 63);
1932 b = MASKED(*rB, 32, 63);
1933 }
1934 else {
1935 a = *rA;
1936 b = *rB;
1937 }
1938 CR_COMPARE(BF, a, b);
1939 }
1940
1941
1942 #
1943 # I.3.3.11 Fixed-Point Trap Instructions
1944 #
1945
1946 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
1947 if (!is_64bit_mode)
1948 program_interrupt(processor, cia,
1949 illegal_instruction_program_interrupt);
1950 else {
1951 signed_word a = *rA;
1952 signed_word b = EXTS(SI);
1953 if ((a < b && TO{0})
1954 || (a > b && TO{1})
1955 || (a == b && TO{2})
1956 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1957 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1958 )
1959 program_interrupt(processor, cia,
1960 trap_program_interrupt);
1961 }
1962
1963 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
1964 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1965 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
1966 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
1967 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
1968 signed_word a = EXTENDED(*rA);
1969 signed_word b = EXTS(SI);
1970 if ((a < b && TO{0})
1971 || (a > b && TO{1})
1972 || (a == b && TO{2})
1973 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1974 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1975 )
1976 program_interrupt(processor, cia,
1977 trap_program_interrupt);
1978
1979 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
1980 if (!is_64bit_mode)
1981 program_interrupt(processor, cia,
1982 illegal_instruction_program_interrupt);
1983 else {
1984 signed_word a = *rA;
1985 signed_word b = *rB;
1986 if ((a < b && TO{0})
1987 || (a > b && TO{1})
1988 || (a == b && TO{2})
1989 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1990 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1991 )
1992 program_interrupt(processor, cia,
1993 trap_program_interrupt);
1994 }
1995
1996 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
1997 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
1998 *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
1999 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
2000 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2001 signed_word a = EXTENDED(*rA);
2002 signed_word b = EXTENDED(*rB);
2003 if (TO == 12 && rA == rB) {
2004 ITRACE(trace_breakpoint, ("breakpoint\n"));
2005 cpu_halt(processor, cia, was_trap, 0);
2006 }
2007 else if ((a < b && TO{0})
2008 || (a > b && TO{1})
2009 || (a == b && TO{2})
2010 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2011 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2012 )
2013 program_interrupt(processor, cia,
2014 trap_program_interrupt);
2015
2016 #
2017 # I.3.3.12 Fixed-Point Logical Instructions
2018 #
2019
2020 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
2021 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2022 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2023 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2024 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2025 *rA = *rS & UI;
2026 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2027
2028 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2029 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2030 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2031 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2032 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2033 *rA = *rS & (UI << 16);
2034 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2035
2036 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
2037 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2038 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2039 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2040 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2041 *rA = *rS | UI;
2042
2043 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2044 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2045 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2046 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2047 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2048 *rA = *rS | (UI << 16);
2049
2050 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2051 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2052 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2053 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2054 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2055 *rA = *rS ^ UI;
2056
2057 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2058 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2059 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2060 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2061 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2062 *rA = *rS ^ (UI << 16);
2063
2064 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
2065 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2066 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2067 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2068 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2069 *rA = *rS & *rB;
2070 CR0_COMPARE(*rA, 0, Rc);
2071
2072 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
2073 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2074 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2075 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2076 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2077 *rA = *rS | *rB;
2078 CR0_COMPARE(*rA, 0, Rc);
2079
2080 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
2081 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2082 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2083 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2084 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2085 *rA = *rS ^ *rB;
2086 CR0_COMPARE(*rA, 0, Rc);
2087
2088 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
2089 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2090 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2091 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2092 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2093 *rA = ~(*rS & *rB);
2094 CR0_COMPARE(*rA, 0, Rc);
2095
2096 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
2097 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2098 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2099 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2100 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2101 *rA = ~(*rS | *rB);
2102 CR0_COMPARE(*rA, 0, Rc);
2103
2104 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
2105 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2106 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2107 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2108 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2109 # *rA = ~(*rS ^ *rB); /* A === B */
2110 # CR0_COMPARE(*rA, 0, Rc);
2111
2112 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
2113 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2114 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2115 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2116 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2117 *rA = *rS & ~*rB;
2118 CR0_COMPARE(*rA, 0, Rc);
2119 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
2120 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2121 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2122 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2123 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2124 *rA = *rS | ~*rB;
2125 CR0_COMPARE(*rA, 0, Rc);
2126
2127 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
2128 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2129 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2130 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2131 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2132 *rA = (signed_word)(signed8)*rS;
2133 CR0_COMPARE(*rA, 0, Rc);
2134
2135 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
2136 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2137 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2138 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2139 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2140 *rA = (signed_word)(signed16)*rS;
2141 CR0_COMPARE(*rA, 0, Rc);
2142
2143 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
2144 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2145 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2146 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2147 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2148 # *rA = (signed_word)(signed32)*rS;
2149 # CR0_COMPARE(*rA, 0, Rc);
2150
2151 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2152 # int count = 0;
2153 # unsigned64 mask = BIT64(0);
2154 # unsigned64 source = *rS;
2155 # while (!(source & mask) && mask != 0) {
2156 # mask >>= 1;
2157 # count++;
2158 # }
2159 # *rA = count;
2160 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2161
2162 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
2163 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2164 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2165 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2166 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2167 int count = 0;
2168 unsigned32 mask = BIT32(0);
2169 unsigned32 source = *rS;
2170 while (!(source & mask) && mask != 0) {
2171 mask >>= 1;
2172 count++;
2173 }
2174 *rA = count;
2175 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2176
2177
2178 #
2179 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
2180 #
2181
2182 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
2183 # long n = (sh_5 << 4) | sh_0_4;
2184 # unsigned_word r = ROTL64(*rS, n);
2185 # long b = (mb_5 << 4) | mb_0_4;
2186 # unsigned_word m = MASK(b, 63);
2187 # signed_word result = r & m;
2188 # *rA = result;
2189 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2190
2191 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
2192 # long n = (sh_5 << 4) | sh_0_4;
2193 # unsigned_word r = ROTL64(*rS, n);
2194 # long e = (me_5 << 4) | me_0_4;
2195 # unsigned_word m = MASK(0, e);
2196 # signed_word result = r & m;
2197 # *rA = result;
2198 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2199
2200 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
2201 # long n = (sh_5 << 4) | sh_0_4;
2202 # unsigned_word r = ROTL64(*rS, n);
2203 # long b = (mb_5 << 4) | mb_0_4;
2204 # unsigned_word m = MASK(0, (64-n));
2205 # signed_word result = r & m;
2206 # *rA = result;
2207 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2208
2209 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
2210 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2211 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2212 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2213 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2214 long n = SH;
2215 unsigned32 s = *rS;
2216 unsigned32 r = ROTL32(s, n);
2217 unsigned32 m = MASK(MB+32, ME+32);
2218 signed_word result = r & m;
2219 *rA = result;
2220 CR0_COMPARE(result, 0, Rc);
2221 ITRACE(trace_alu,
2222 ("n=%d, s=0x%x, r=0x%x, m=0x%x, result=0x%x, cr=0x%x\n",
2223 n, s, r, m, result, CR));
2224
2225 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2226 # long n = MASKED(*rB, 58, 63);
2227 # unsigned_word r = ROTL64(*rS, n);
2228 # long b = (mb_5 << 4) | mb_0_4;
2229 # unsigned_word m = MASK(b, 63);
2230 # signed_word result = r & m;
2231 # *rA = result;
2232 # CR0_COMPARE(result, 0, Rc);
2233
2234 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2235 # long n = MASKED(*rB, 58, 63);
2236 # unsigned_word r = ROTL64(*rS, n);
2237 # long e = (me_5 << 4) | me_0_4;
2238 # unsigned_word m = MASK(0, e);
2239 # signed_word result = r & m;
2240 # *rA = result;
2241 # CR0_COMPARE(result, 0, Rc);
2242
2243 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2244 # long n = MASKED(*rB, 59, 63);
2245 # unsigned32 r = ROTL32(*rS, n);
2246 # unsigned32 m = MASK(MB+32, ME+32);
2247 # signed_word result = r & m;
2248 # *rA = result;
2249 # CR0_COMPARE(result, 0, Rc);
2250
2251 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
2252 # long n = (sh_5 << 4) | sh_0_4;
2253 # unsigned_word r = ROTL64(*rS, n);
2254 # long b = (mb_5 << 4) | mb_0_4;
2255 # unsigned_word m = MASK(b, (64-n));
2256 # signed_word result = (r & m) | (*rA & ~m)
2257 # *rA = result;
2258 # CR0_COMPARE(result, 0, Rc);
2259
2260 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
2261 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2262 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2263 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2264 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2265 long n = SH;
2266 unsigned32 r = ROTL32(*rS, n);
2267 unsigned32 m = MASK(MB+32, ME+32);
2268 signed_word result = (r & m) | (*rA & ~m);
2269 *rA = result;
2270 ITRACE(trace_alu, (": n=%d *rS=0x%x r=0x%x m=0x%x result=0x%x\n",
2271 n, *rS, r, m, result));
2272 CR0_COMPARE(result, 0, Rc);
2273
2274
2275 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
2276
2277 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
2278 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2279 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2280 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2281 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2282 int n = MASKED(*rB, 59, 63);
2283 unsigned32 source = *rS;
2284 signed_word shifted;
2285 if (n < 32)
2286 shifted = (source << n);
2287 else
2288 shifted = 0;
2289 *rA = shifted;
2290 CR0_COMPARE(shifted, 0, Rc);
2291 ITRACE(trace_alu,
2292 ("n=%d, source=0x%x, shifted=0x%x\n",
2293 n, source, shifted));
2294
2295 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
2296
2297 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
2298 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2299 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2300 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2301 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2302 int n = MASKED(*rB, 59, 63);
2303 unsigned32 source = *rS;
2304 signed_word shifted;
2305 if (n < 32)
2306 shifted = (source >> n);
2307 else
2308 shifted = 0;
2309 *rA = shifted;
2310 CR0_COMPARE(shifted, 0, Rc);
2311 ITRACE(trace_alu, \
2312 ("n=%d, source=0x%x, shifted=0x%x\n",
2313 n, source, shifted));
2314
2315 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
2316
2317 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
2318 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2319 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2320 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2321 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2322 int n = SH;
2323 signed_word r = ROTL32(*rS, /*64*/32-n);
2324 signed_word m = MASK(n+32, 63);
2325 int S = MASKED(*rS, 32, 32);
2326 signed_word shifted = (r & m) | (S ? ~m : 0);
2327 *rA = shifted;
2328 if (S && ((r & ~m) & MASK(32, 63)) != 0)
2329 XER |= xer_carry;
2330 else
2331 XER &= ~xer_carry;
2332 CR0_COMPARE(shifted, 0, Rc);
2333
2334 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
2335
2336 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
2337 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2338 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2339 *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2340 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, ppc_insn_generic
2341 int n = MASKED(*rB, 58, 63);
2342 int shift = (n >= 31 ? 31 : n);
2343 signed32 source = (signed32)*rS; /* signed to keep sign bit */
2344 signed32 shifted = source >> shift;
2345 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
2346 *rA = (signed_word)shifted; /* if 64bit will sign extend */
2347 if (source < 0 && (source & mask))
2348 XER |= xer_carry;
2349 else
2350 XER &= ~xer_carry;
2351 CR0_COMPARE(shifted, 0, Rc);
2352
2353
2354 #
2355 # I.3.3.14 Move to/from System Register Instructions
2356 #
2357
2358 0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
2359 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2360 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
2361 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
2362 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
2363 int n = (spr{5:9} << 5) | spr{0:4};
2364 if (spr{0} && IS_PROBLEM_STATE(processor))
2365 program_interrupt(processor, cia,
2366 privileged_instruction_program_interrupt);
2367 else if (!spr_is_valid(n)
2368 || spr_is_readonly(n))
2369 program_interrupt(processor, cia,
2370 illegal_instruction_program_interrupt);
2371 else {
2372 spreg new_val = (spr_length(n) == 64
2373 ? *rS
2374 : MASKED(*rS, 32, 63));
2375 /* HACK - time base registers need to be updated immediatly */
2376 if (WITH_TIME_BASE) {
2377 signed64 time_base;
2378 switch (n) {
2379 case spr_tbu:
2380 cpu_set_time_base(processor,
2381 (MASKED64(cpu_get_time_base(processor), 32, 63)
2382 | INSERTED64(new_val, 0, 31)));
2383 break;
2384 case spr_tbl:
2385 cpu_set_time_base(processor,
2386 (MASKED64(cpu_get_time_base(processor), 0, 31)
2387 | INSERTED64(new_val, 32, 63)));
2388 break;
2389 case spr_dec:
2390 cpu_set_decrementer(processor, new_val);
2391 break;
2392 default:
2393 SPREG(n) = new_val;
2394 break;
2395 }
2396 }
2397 else {
2398 SPREG(n) = new_val;
2399 }
2400 }
2401
2402 0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
2403 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2404 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2405 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2406 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
2407 int n = (spr{5:9} << 5) | spr{0:4};
2408 if (spr{0} && IS_PROBLEM_STATE(processor))
2409 program_interrupt(processor, cia,
2410 privileged_instruction_program_interrupt);
2411 else if (!spr_is_valid(n))
2412 program_interrupt(processor, cia,
2413 illegal_instruction_program_interrupt);
2414 else {
2415 /* HACK - some SPR's need to get their value extracted specially */
2416 *rT = SPREG(n);
2417 }
2418
2419 # FIXME: 604 uses SCIU{1,2} if only one bit is being set
2420 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
2421 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
2422 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2423 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2424 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
2425 if (FXM == 0xff) {
2426 CR = *rS;
2427 }
2428 else {
2429 unsigned_word mask = 0;
2430 unsigned_word f;
2431 for (f = 0; f < 8; f++) {
2432 if (FXM & (0x80 >> f))
2433 mask |= (0xf << 4*(7-f));
2434 }
2435 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
2436 }
2437
2438 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
2439
2440 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
2441 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2442 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2443 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
2444 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
2445 *rT = (unsigned32)CR;
2446
2447 #
2448 # I.4.6.2 Floating-Point Load Instructions
2449 #
2450
2451 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
2452 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2453 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2454 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2455 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2456 unsigned_word b;
2457 unsigned_word EA;
2458 if (RA == 0) b = 0;
2459 else b = *rA;
2460 EA = b + EXTS(D);
2461 *frT = DOUBLE(MEM(unsigned, EA, 4));
2462
2463 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
2464 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2465 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2466 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2467 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2468 unsigned_word b;
2469 unsigned_word EA;
2470 if (RA == 0) b = 0;
2471 else b = *rA;
2472 EA = b + *rB;
2473 *frT = DOUBLE(MEM(unsigned, EA, 4));
2474
2475 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
2476 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2477 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2478 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2479 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2480 unsigned_word EA;
2481 if (RA == 0)
2482 program_interrupt(processor, cia,
2483 illegal_instruction_program_interrupt);
2484 EA = *rA + EXTS(D);
2485 *frT = DOUBLE(MEM(unsigned, EA, 4));
2486 *rA = EA;
2487
2488 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
2489 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2490 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2491 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2492 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2493 unsigned_word EA;
2494 if (RA == 0)
2495 program_interrupt(processor, cia,
2496 illegal_instruction_program_interrupt);
2497 EA = *rA + *rB;
2498 *frT = DOUBLE(MEM(unsigned, EA, 4));
2499 *rA = EA;
2500
2501 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
2502 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2503 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2504 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2505 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2506 unsigned_word b;
2507 unsigned_word EA;
2508 if (RA == 0) b = 0;
2509 else b = *rA;
2510 EA = b + EXTS(D);
2511 *frT = MEM(unsigned, EA, 8);
2512
2513 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
2514 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2515 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2516 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2517 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2518 unsigned_word b;
2519 unsigned_word EA;
2520 if (RA == 0) b = 0;
2521 else b = *rA;
2522 EA = b + *rB;
2523 *frT = MEM(unsigned, EA, 8);
2524
2525 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
2526 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2527 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2528 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2529 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2530 unsigned_word EA;
2531 if (RA == 0)
2532 program_interrupt(processor, cia,
2533 illegal_instruction_program_interrupt);
2534 EA = *rA + EXTS(D);
2535 *frT = MEM(unsigned, EA, 8);
2536 *rA = EA;
2537
2538 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
2539 *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, ppc_insn_generic
2540 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2541 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2542 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2543 unsigned_word EA;
2544 if (RA == 0)
2545 program_interrupt(processor, cia,
2546 illegal_instruction_program_interrupt);
2547 EA = *rA + *rB;
2548 *frT = MEM(unsigned, EA, 8);
2549 *rA = EA;
2550
2551
2552 #
2553 # I.4.6.3 Floating-Point Store Instructions
2554 #
2555
2556 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
2557 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2558 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2559 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2560 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2561 unsigned_word b;
2562 unsigned_word EA;
2563 if (RA == 0) b = 0;
2564 else b = *rA;
2565 EA = b + EXTS(D);
2566 STORE(EA, 4, SINGLE(*frS));
2567
2568 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
2569 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2570 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2571 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2572 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2573 unsigned_word b;
2574 unsigned_word EA;
2575 if (RA == 0) b = 0;
2576 else b = *rA;
2577 EA = b + *rB;
2578 STORE(EA, 4, SINGLE(*frS));
2579
2580 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
2581 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2582 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2583 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2584 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2585 unsigned_word EA;
2586 if (RA == 0)
2587 program_interrupt(processor, cia,
2588 illegal_instruction_program_interrupt);
2589 EA = *rA + EXTS(D);
2590 STORE(EA, 4, SINGLE(*frS));
2591 *rA = EA;
2592
2593 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
2594 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2595 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2596 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2597 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2598 unsigned_word EA;
2599 if (RA == 0)
2600 program_interrupt(processor, cia,
2601 illegal_instruction_program_interrupt);
2602 EA = *rA + *rB;
2603 STORE(EA, 4, SINGLE(*frS));
2604 *rA = EA;
2605
2606 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
2607 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2608 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2609 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2610 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2611 unsigned_word b;
2612 unsigned_word EA;
2613 if (RA == 0) b = 0;
2614 else b = *rA;
2615 EA = b + EXTS(D);
2616 STORE(EA, 8, *frS);
2617
2618 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
2619 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2620 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2621 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2622 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2623 unsigned_word b;
2624 unsigned_word EA;
2625 if (RA == 0) b = 0;
2626 else b = *rA;
2627 EA = b + *rB;
2628 STORE(EA, 8, *frS);
2629
2630 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
2631 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2632 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2633 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2634 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2635 unsigned_word EA;
2636 if (RA == 0)
2637 program_interrupt(processor, cia,
2638 illegal_instruction_program_interrupt);
2639 EA = *rA + EXTS(D);
2640 STORE(EA, 8, *frS);
2641 *rA = EA;
2642
2643 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
2644 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
2645 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2646 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, ppc_insn_generic
2647 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
2648 unsigned_word EA;
2649 if (RA == 0)
2650 program_interrupt(processor, cia,
2651 illegal_instruction_program_interrupt);
2652 EA = *rA + *rB;
2653 STORE(EA, 8, *frS);
2654 *rA = EA;
2655
2656
2657 #
2658 # I.4.6.4 Floating-Point Move Instructions
2659 #
2660
2661 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
2662 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2663 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2664 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2665 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2666 *frT = *frB;
2667 CR1_UPDATE(Rc);
2668
2669 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
2670 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2671 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2672 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2673 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2674 *frT = *frB ^ BIT64(0);
2675 CR1_UPDATE(Rc);
2676
2677 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
2678 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2679 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2680 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2681 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2682 *frT = *frB & ~BIT64(0);
2683 CR1_UPDATE(Rc);
2684
2685 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
2686 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2687 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2688 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2689 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2690 *frT = *frB | BIT64(0);
2691 CR1_UPDATE(Rc);
2692
2693
2694
2695 #
2696 # I.4.6.5 Floating-Point Arithmetic Instructions
2697 #
2698
2699 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
2700 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2701 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2702 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2703 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2704 FPSCR_BEGIN;
2705 if (is_invalid_operation(processor, cia,
2706 *frA, *frB,
2707 fpscr_vxsnan | fpscr_vxisi,
2708 0, /*single?*/
2709 0) /*negate?*/) {
2710 invalid_arithemetic_operation(processor, cia,
2711 frT, *frA, *frB, 0,
2712 0, /*instruction_is_frsp*/
2713 0, /*instruction_is_convert_to_64bit*/
2714 0, /*instruction_is_convert_to_32bit*/
2715 0); /*single-precision*/
2716 }
2717 else {
2718 /*HACK!*/
2719 double s = *(double*)frA + *(double*)frB;
2720 *(double*)frT = s;
2721 }
2722 FPSCR_END(Rc);
2723
2724 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
2725 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2726 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2727 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2728 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2729 FPSCR_BEGIN;
2730 if (is_invalid_operation(processor, cia,
2731 *frA, *frB,
2732 fpscr_vxsnan | fpscr_vxisi,
2733 1, /*single?*/
2734 0) /*negate?*/) {
2735 invalid_arithemetic_operation(processor, cia,
2736 frT, *frA, *frB, 0,
2737 0, /*instruction_is_frsp*/
2738 0, /*instruction_is_convert_to_64bit*/
2739 0, /*instruction_is_convert_to_32bit*/
2740 1); /*single-precision*/
2741 }
2742 else {
2743 /*HACK!*/
2744 float s = *(double*)frA + *(double*)frB;
2745 *(double*)frT = s;
2746 }
2747 FPSCR_END(Rc);
2748
2749 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
2750 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2751 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2752 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2753 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2754 FPSCR_BEGIN;
2755 if (is_invalid_operation(processor, cia,
2756 *frA, *frB,
2757 fpscr_vxsnan | fpscr_vxisi,
2758 0, /*single?*/
2759 1) /*negate?*/) {
2760 invalid_arithemetic_operation(processor, cia,
2761 frT, *frA, *frB, 0,
2762 0, /*instruction_is_frsp*/
2763 0, /*instruction_is_convert_to_64bit*/
2764 0, /*instruction_is_convert_to_32bit*/
2765 0); /*single-precision*/
2766 }
2767 else {
2768 /*HACK!*/
2769 double s = *(double*)frA - *(double*)frB;
2770 *(double*)frT = s;
2771 }
2772 FPSCR_END(Rc);
2773
2774 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
2775 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2776 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2777 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2778 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2779 FPSCR_BEGIN;
2780 if (is_invalid_operation(processor, cia,
2781 *frA, *frB,
2782 fpscr_vxsnan | fpscr_vxisi,
2783 1, /*single?*/
2784 1) /*negate?*/) {
2785 invalid_arithemetic_operation(processor, cia,
2786 frT, *frA, *frB, 0,
2787 0, /*instruction_is_frsp*/
2788 0, /*instruction_is_convert_to_64bit*/
2789 0, /*instruction_is_convert_to_32bit*/
2790 1); /*single-precision*/
2791 }
2792 else {
2793 /*HACK!*/
2794 float s = *(double*)frA - *(double*)frB;
2795 *(double*)frT = s;
2796 }
2797 FPSCR_END(Rc);
2798
2799 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
2800 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2801 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2802 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2803 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2804 FPSCR_BEGIN;
2805 if (is_invalid_operation(processor, cia,
2806 *frA, *frC,
2807 fpscr_vxsnan | fpscr_vximz,
2808 0, /*single?*/
2809 0) /*negate?*/) {
2810 invalid_arithemetic_operation(processor, cia,
2811 frT, *frA, 0, *frC,
2812 0, /*instruction_is_frsp*/
2813 0, /*instruction_is_convert_to_64bit*/
2814 0, /*instruction_is_convert_to_32bit*/
2815 0); /*single-precision*/
2816 }
2817 else {
2818 /*HACK!*/
2819 double s = *(double*)frA * *(double*)frC;
2820 *(double*)frT = s;
2821 }
2822 FPSCR_END(Rc);
2823
2824 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
2825 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2826 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2827 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2828 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2829 FPSCR_BEGIN;
2830 if (is_invalid_operation(processor, cia,
2831 *frA, *frC,
2832 fpscr_vxsnan | fpscr_vximz,
2833 1, /*single?*/
2834 0) /*negate?*/) {
2835 invalid_arithemetic_operation(processor, cia,
2836 frT, *frA, 0, *frC,
2837 0, /*instruction_is_frsp*/
2838 0, /*instruction_is_convert_to_64bit*/
2839 0, /*instruction_is_convert_to_32bit*/
2840 1); /*single-precision*/
2841 }
2842 else {
2843 /*HACK!*/
2844 float s = *(double*)frA * *(double*)frC;
2845 *(double*)frT = s;
2846 }
2847 FPSCR_END(Rc);
2848
2849 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
2850 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, ppc_insn_generic
2851 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, ppc_insn_generic
2852 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, ppc_insn_generic
2853 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, ppc_insn_generic
2854 FPSCR_BEGIN;
2855 if (is_invalid_operation(processor, cia,
2856 *frA, *frB,
2857 fpscr_vxsnan | fpscr_vxzdz,
2858 0, /*single?*/
2859 0) /*negate?*/) {
2860 invalid_arithemetic_operation(processor, cia,
2861 frT, *frA, *frB, 0,
2862 0, /*instruction_is_frsp*/
2863 0, /*instruction_is_convert_to_64bit*/
2864 0, /*instruction_is_convert_to_32bit*/
2865 0); /*single-precision*/
2866 }
2867 else {
2868 /*HACK!*/
2869 double s = *(double*)frA / *(double*)frB;
2870 *(double*)frT = s;
2871 }
2872 FPSCR_END(Rc);
2873
2874 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
2875 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, ppc_insn_generic
2876 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, ppc_insn_generic
2877 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, ppc_insn_generic
2878 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, ppc_insn_generic
2879 FPSCR_BEGIN;
2880 if (is_invalid_operation(processor, cia,
2881 *frA, *frB,
2882 fpscr_vxsnan | fpscr_vxzdz,
2883 1, /*single?*/
2884 0) /*negate?*/) {
2885 invalid_arithemetic_operation(processor, cia,
2886 frT, *frA, *frB, 0,
2887 0, /*instruction_is_frsp*/
2888 0, /*instruction_is_convert_to_64bit*/
2889 0, /*instruction_is_convert_to_32bit*/
2890 1); /*single-precision*/
2891 }
2892 else {
2893 /*HACK!*/
2894 float s = *(double*)frA / *(double*)frB;
2895 *(double*)frT = s;
2896 }
2897 FPSCR_END(Rc);
2898
2899 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
2900 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2901 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2902 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2903 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2904 FPSCR_BEGIN;
2905 double product; /*HACK! - incorrectly loosing precision ... */
2906 /* compute the multiply */
2907 if (is_invalid_operation(processor, cia,
2908 *frA, *frC,
2909 fpscr_vxsnan | fpscr_vximz,
2910 0, /*single?*/
2911 0) /*negate?*/) {
2912 invalid_arithemetic_operation(processor, cia,
2913 (unsigned64*)&product, *frA, 0, *frC,
2914 0, /*instruction_is_frsp*/
2915 0, /*instruction_is_convert_to_64bit*/
2916 0, /*instruction_is_convert_to_32bit*/
2917 0); /*single-precision*/
2918 }
2919 else {
2920 /*HACK!*/
2921 product = *(double*)frA * *(double*)frC;
2922 }
2923 /* compute the add */
2924 if (is_invalid_operation(processor, cia,
2925 product, *frB,
2926 fpscr_vxsnan | fpscr_vxisi,
2927 0, /*single?*/
2928 0) /*negate?*/) {
2929 invalid_arithemetic_operation(processor, cia,
2930 frT, product, *frB, 0,
2931 0, /*instruction_is_frsp*/
2932 0, /*instruction_is_convert_to_64bit*/
2933 0, /*instruction_is_convert_to_32bit*/
2934 0); /*single-precision*/
2935 }
2936 else {
2937 /*HACK!*/
2938 double s = product + *(double*)frB;
2939 *(double*)frT = s;
2940 }
2941 FPSCR_END(Rc);
2942
2943 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
2944 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2945 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2946 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2947 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2948
2949 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
2950 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2951 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2952 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2953 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2954
2955 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
2956 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2957 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2958 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2959 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2960
2961 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
2962 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2963 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2964 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2965 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2966
2967 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
2968 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2969 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2970 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2971 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2972
2973 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
2974 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, ppc_insn_generic
2975 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2976 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, ppc_insn_generic
2977 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2978
2979 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
2980 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2981 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2982 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2983 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2984
2985
2986 #
2987 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
2988 #
2989
2990 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
2991 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
2992 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2993 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2994 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
2995 int sign;
2996 int exp;
2997 unsigned64 frac_grx;
2998 /* split off cases for what to do */
2999 if (EXTRACTED64(*frB, 1, 11) < 897
3000 && EXTRACTED64(*frB, 1, 63) > 0) {
3001 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
3002 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
3003 }
3004 if (EXTRACTED64(*frB, 1, 11) > 1150
3005 && EXTRACTED64(*frB, 1, 11) < 2047) {
3006 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3007 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
3008 }
3009 if (EXTRACTED64(*frB, 1, 11) > 896
3010 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
3011 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
3012 if (EXTRACTED64(*frB, 1, 11) == 2047) {
3013 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
3014 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
3015 if (EXTRACTED64(*frB, 12, 12) == 0
3016 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
3017 }
3018 /* handle them */
3019 Disabled_Exponent_Underflow:
3020 sign = EXTRACTED64(*frB, 0, 0);
3021 if (EXTRACTED64(*frB, 1, 11) == 0) {
3022 exp = -1022;
3023 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3024 }
3025 if (EXTRACTED64(*frB, 1, 11) > 0) {
3026 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3027 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3028 }
3029 Denormalize_Operand:
3030 /* G|R|X == zero from above */
3031 while (exp < -126) {
3032 exp = exp - 1;
3033 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
3034 | MASKED64(frac_grx, 55, 55));
3035 }
3036 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
3037 Round_Single(processor, sign, &exp, &frac_grx);
3038 FPSCR_SET_XX(FPSCR & fpscr_fi);
3039 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
3040 *frT = INSERTED64(sign, 0, 0);
3041 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3042 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3043 }
3044 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
3045 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
3046 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3047 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3048 }
3049 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
3050 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
3051 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
3052 }
3053 /*Normalize_Operand:*/
3054 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3055 exp = exp - 1;
3056 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3057 }
3058 *frT = (INSERTED64(sign, 0, 0)
3059 | INSERTED64(exp + 1023, 1, 11)
3060 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3061 }
3062 goto Done;
3063 Enabled_Exponent_Underflow:
3064 FPSCR_SET_UX(1);
3065 sign = EXTRACTED64(*frB, 0, 0);
3066 if (EXTRACTED64(*frB, 1, 11) == 0) {
3067 exp = -1022;
3068 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3069 }
3070 if (EXTRACTED64(*frB, 1, 11) > 0) {
3071 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3072 frac_grx = (BIT64(0) |
3073 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
3074 }
3075 /*Normalize_Operand:*/
3076 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3077 exp = exp - 1;
3078 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3079 }
3080 Round_Single(processor, sign, &exp, &frac_grx);
3081 FPSCR_SET_XX(FPSCR & fpscr_fi);
3082 exp = exp + 192;
3083 *frT = (INSERTED64(sign, 0, 0)
3084 | INSERTED64(exp + 1023, 1, 11)
3085 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3086 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3087 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3088 goto Done;
3089 Disabled_Exponent_Overflow:
3090 FPSCR_SET_OX(1);
3091 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
3092 if (EXTRACTED64(*frB, 0, 0) == 0) {
3093 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
3094 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3095 }
3096 if (EXTRACTED64(*frB, 0, 0) == 1) {
3097 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
3098 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3099 }
3100 }
3101 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
3102 if (EXTRACTED64(*frB, 0, 0) == 0) {
3103 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
3104 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3105 }
3106 if (EXTRACTED64(*frB, 0, 0) == 1) {
3107 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
3108 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3109 }
3110 }
3111 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
3112 if (EXTRACTED64(*frB, 0, 0) == 0) {
3113 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
3114 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3115 }
3116 if (EXTRACTED64(*frB, 0, 0) == 1) {
3117 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
3118 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3119 }
3120 }
3121 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
3122 if (EXTRACTED64(*frB, 0, 0) == 0) {
3123 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
3124 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3125 }
3126 if (EXTRACTED64(*frB, 0, 0) == 1) {
3127 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
3128 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3129 }
3130 }
3131 /* FPSCR[FR] <- undefined */
3132 FPSCR_SET_FI(1);
3133 FPSCR_SET_XX(1);
3134 goto Done;
3135 Enabled_Exponent_Overflow:
3136 sign = EXTRACTED64(*frB, 0, 0);
3137 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3138 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3139 Round_Single(processor, sign, &exp, &frac_grx);
3140 FPSCR_SET_XX(FPSCR & fpscr_fi);
3141 Enabled_Overflow:
3142 FPSCR_SET_OX(1);
3143 exp = exp - 192;
3144 *frT = (INSERTED64(sign, 0, 0)
3145 | INSERTED64(exp + 1023, 1, 11)
3146 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3147 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3148 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3149 goto Done;
3150 Zero_Operand:
3151 *frT = *frB;
3152 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3153 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3154 FPSCR_SET_FR(0);
3155 FPSCR_SET_FI(0);
3156 goto Done;
3157 Infinity_Operand:
3158 *frT = *frB;
3159 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
3160 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
3161 FPSCR_SET_FR(0);
3162 FPSCR_SET_FI(0);
3163 goto Done;
3164 QNaN_Operand:
3165 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
3166 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
3167 FPSCR_SET_FR(0);
3168 FPSCR_SET_FI(0);
3169 goto Done;
3170 SNaN_Operand:
3171 FPSCR_OR_VX(fpscr_vxsnan);
3172 if ((FPSCR & fpscr_ve) == 0) {
3173 *frT = (MASKED64(*frB, 0, 11)
3174 | BIT64(12)
3175 | MASKED64(*frB, 13, 34));
3176 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
3177 }
3178 FPSCR_SET_FR(0);
3179 FPSCR_SET_FI(0);
3180 goto Done;
3181 Normal_Operand:
3182 sign = EXTRACTED64(*frB, 0, 0);
3183 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3184 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3185 Round_Single(processor, sign, &exp, &frac_grx);
3186 FPSCR_SET_XX(FPSCR & fpscr_fi);
3187 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3188 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
3189 *frT = (INSERTED64(sign, 0, 0)
3190 | INSERTED64(exp + 1023, 1, 11)
3191 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3192 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3193 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3194 goto Done;
3195 Done:
3196
3197 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
3198
3199 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
3200
3201 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
3202
3203 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
3204 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
3205 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3206 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3207 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3208 FPSCR_BEGIN;
3209 convert_to_integer(processor, cia,
3210 frT, *frB,
3211 fpscr_rn_round_towards_zero, 32);
3212 FPSCR_END(Rc);
3213
3214 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
3215 int sign = EXTRACTED64(*frB, 0, 0);
3216 int exp = 63;
3217 unsigned64 frac = *frB;
3218 if (frac == 0) goto Zero_Operand;
3219 if (sign == 1) frac = ~frac + 1;
3220 while (EXTRACTED64(frac, 0, 0) == 0) {
3221 /*??? do the loop 0 times if (FRB) = max negative integer */
3222 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
3223 exp = exp - 1;
3224 }
3225 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
3226 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3227 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3228 *frT = (INSERTED64(sign, 0, 0)
3229 | INSERTED64(exp + 1023, 1, 11)
3230 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
3231 goto Done;
3232 /**/
3233 Zero_Operand:
3234 FPSCR_SET_FR(0);
3235 FPSCR_SET_FI(0);
3236 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3237 *frT = 0;
3238 goto Done;
3239 /**/
3240 Done:
3241
3242 #
3243 # I.4.6.7 Floating-Point Compare Instructions
3244 #
3245
3246 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
3247 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
3248 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3249 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3250 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3251 FPSCR_BEGIN;
3252 unsigned c;
3253 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3254 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3255 else if (is_less_than(frA, frB))
3256 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3257 else if (is_greater_than(frA, frB))
3258 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3259 else
3260 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3261 FPSCR_SET_FPCC(c);
3262 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3263 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
3264 FPSCR_OR_VX(fpscr_vxsnan);
3265 FPSCR_END(0);
3266
3267 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
3268 *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, ppc_insn_generic
3269 *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3270 *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3271 *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, ppc_insn_generic
3272 FPSCR_BEGIN;
3273 unsigned c;
3274 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
3275 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
3276 else if (is_less_than(frA, frB))
3277 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
3278 else if (is_greater_than(frA, frB))
3279 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
3280 else
3281 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
3282 FPSCR_SET_FPCC(c);
3283 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
3284 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
3285 FPSCR_OR_VX(fpscr_vxsnan);
3286 if ((FPSCR & fpscr_ve) == 0)
3287 FPSCR_OR_VX(fpscr_vxvc);
3288 }
3289 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
3290 FPSCR_OR_VX(fpscr_vxvc);
3291 }
3292 FPSCR_END(0);
3293
3294
3295 #
3296 # I.4.6.8 Floating-Point Status and Control Register Instructions
3297 #
3298
3299 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
3300
3301 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
3302
3303 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
3304
3305 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
3306
3307 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
3308
3309 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
3310
3311
3312 #
3313 # I.A.1.1 Floating-Point Store Instruction
3314 #
3315 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
3316
3317 #
3318 # I.A.1.2 Floating-Point Arithmetic Instructions
3319 #
3320
3321 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
3322
3323 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
3324
3325 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
3326
3327 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
3328
3329 #
3330 # I.A.1.3 Floating-Point Select Instruction
3331 #
3332
3333 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
3334
3335
3336 #
3337 # II.3.2 Cache Management Instructions
3338 #
3339
3340 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
3341 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3342 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3343 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3344 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3345 /* blindly flush all instruction cache entries */
3346 #if WITH_IDECODE_CACHE_SIZE
3347 cpu_flush_icache(processor);
3348 #endif
3349
3350 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
3351 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3352 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3353 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3354 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3355 cpu_synchronize_context(processor);
3356
3357
3358 #
3359 # II.3.2.2 Data Cache Instructions
3360 #
3361
3362 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
3363 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3364 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3365 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3366 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3367 TRACE(trace_tbd,("Data Cache Block Touch\n"));
3368
3369 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
3370 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3371 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3372 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3373 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3374 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
3375
3376 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
3377 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3378 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, ppc_insn_generic
3379 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, ppc_insn_generic
3380 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3381 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
3382
3383 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
3384 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3385 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, ppc_insn_generic
3386 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, ppc_insn_generic
3387 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3388 TRACE(trace_tbd,("Data Cache Block Store\n"));
3389
3390 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
3391 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3392 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, ppc_insn_generic
3393 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, ppc_insn_generic
3394 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, ppc_insn_generic
3395 TRACE(trace_tbd,("Data Cache Block Flush\n"));
3396
3397 #
3398 # II.3.3 Enforce In-order Execution of I/O Instruction
3399 #
3400
3401 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
3402 /* Since this model has no instruction overlap
3403 this instruction need do nothing */
3404
3405 #
3406 # II.4.1 Time Base Instructions
3407 #
3408
3409 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
3410 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
3411 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
3412 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
3413 int n = (tbr{5:9} << 5) | tbr{0:4};
3414 if (n == 268) {
3415 if (is_64bit_implementation) *rT = TB;
3416 else *rT = EXTRACTED64(TB, 32, 63);
3417 }
3418 else if (n == 269) {
3419 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
3420 else *rT = EXTRACTED64(TB, 0, 31);
3421 }
3422 else
3423 program_interrupt(processor, cia,
3424 illegal_instruction_program_interrupt);
3425
3426
3427 #
3428 # III.2.3.1 System Linkage Instructions
3429 #
3430
3431 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
3432 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3433 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3434 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3435 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
3436 if (IS_PROBLEM_STATE(processor)) {
3437 program_interrupt(processor, cia,
3438 privileged_instruction_program_interrupt);
3439 }
3440 else {
3441 MSR = (MASKED(SRR1, 0, 32)
3442 | MASKED(SRR1, 37, 41)
3443 | MASKED(SRR1, 48, 63));
3444 NIA = MASKED(SRR0, 0, 61);
3445 cpu_synchronize_context(processor);
3446 }
3447
3448 #
3449 # III.3.4.1 Move to/from System Register Instructions
3450 #
3451
3452 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
3453 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
3454 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
3455 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3456 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3457 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3458 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3459 if (IS_PROBLEM_STATE(processor))
3460 program_interrupt(processor, cia,
3461 privileged_instruction_program_interrupt);
3462 else
3463 MSR = *rS;
3464
3465 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
3466 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3467 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
3468 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, ppc_insn_generic
3469 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, ppc_insn_generic
3470 if (IS_PROBLEM_STATE(processor))
3471 program_interrupt(processor, cia,
3472 privileged_instruction_program_interrupt);
3473 else
3474 *rT = MSR;
3475
3476
3477 #
3478 # III.4.11.1 Cache Management Instructions
3479 #
3480
3481 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
3482 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3483 *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3484 *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, ppc_insn_generic
3485 *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, ppc_insn_generic
3486 if (IS_PROBLEM_STATE(processor))
3487 program_interrupt(processor, cia,
3488 privileged_instruction_program_interrupt);
3489 else
3490 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
3491
3492 #
3493 # III.4.11.2 Segment Register Manipulation Instructions
3494 #
3495
3496 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
3497 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3498 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3499 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3500 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3501 if (IS_PROBLEM_STATE(processor))
3502 program_interrupt(processor, cia,
3503 privileged_instruction_program_interrupt);
3504 else
3505 SEGREG(SR) = *rS;
3506
3507 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
3508 *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, ppc_insn_generic
3509 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3510 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, ppc_insn_generic
3511 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3512 if (IS_PROBLEM_STATE(processor))
3513 program_interrupt(processor, cia,
3514 privileged_instruction_program_interrupt);
3515 else
3516 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
3517
3518 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
3519 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
3520 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3521 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3522 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3523 if (IS_PROBLEM_STATE(processor))
3524 program_interrupt(processor, cia,
3525 privileged_instruction_program_interrupt);
3526 else
3527 *rT = SEGREG(SR);
3528
3529 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
3530 *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, ppc_insn_generic
3531 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3532 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, ppc_insn_generic
3533 *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, ppc_insn_generic
3534 if (IS_PROBLEM_STATE(processor))
3535 program_interrupt(processor, cia,
3536 privileged_instruction_program_interrupt);
3537 else
3538 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
3539
3540
3541 #
3542 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
3543 #
3544
3545 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
3546
3547 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
3548
3549 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
3550
3551 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
3552
3553 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
3554
3555
3556 #
3557 # III.A.1.2 External Access Instructions
3558 #
3559
3560 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
3561
3562 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
This page took 0.152997 seconds and 5 git commands to generate.