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