fix bug in last checkin
[external/binutils.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, cpu *processor, 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