Add support for setting model name and other things
[deliverable/binutils-gdb.git] / sim / ppc / ppc-instructions
1 #
2 # This file is part of the program psim.
3 #
4 # Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
5 #
6 # --
7 #
8 # The pseudo-code that appears below, translated into C, was copied
9 # by Andrew Cagney of Moss Vale, Australia.
10 #
11 # This pseudo-code is copied by permission from the publication
12 # "The PowerPC Architecture: A Specification for A New Family of
13 # RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by
14 # International Business Machines Corporation.
15 #
16 # THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER
17 # EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES
18 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 #
20 # --
21 #
22 # This program is free software; you can redistribute it and/or modify
23 # it under the terms of the GNU General Public License as published by
24 # the Free Software Foundation; either version 2 of the License, or
25 # (at your option) any later version.
26 #
27 # This program is distributed in the hope that it will be useful,
28 # but WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 # GNU General Public License for more details.
31 #
32 # You should have received a copy of the GNU General Public License
33 # along with this program; if not, write to the Free Software
34 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #
36 # --
37 #
38 #
39 # Fields:
40 #
41 # 1 Instruction format as a `start-bit,content' pairs.
42 # the content is one of a digit, field name or `/' (aka.0)
43 #
44 # 2 Format specifier
45 #
46 # 3 Flags: 64 - 64bit only
47 # f - floating point enabled required
48 #
49 # 4 short name
50 #
51 # 5 Description
52 #
53 #
54 # For flags marked 'model', the fields are interpreted as follows:
55 #
56 # 1 Not used
57 #
58 # 2 Not used
59 #
60 # 3 "macro"
61 #
62 # 4 String name for model
63 #
64 # 5 Specific CPU model, must be an identifier
65 #
66 # 6 Comma separated list of functional units
67
68 # Flags for model.h
69 ::model-macro:::#define PPC_LOAD 0x00000001
70 ::model-macro:::#define PPC_STORE 0x00000002
71 ::model-macro:::#define PPC_SERIALIZE 0x00000004
72
73 # PowerPC models
74 ::model:604:PPC604:SCIU=2 single cycle integer,MCIU=1 multiple cycle integer,FPU=1 floating point,LSU=1 memory,BPU=1 branch
75 ::model:603e:PPC603e:IU=1 integer,FPU=1 floating point,LSU=1 memory,SRU=1 system register,BPU=1 branch
76 ::model:603:PPC603:IU=1 integer,FPU=1 floating point,LSU=1 memory,SRU=1 system register,BPU=1 branch
77
78
79 # The following (illegal) instruction is `known' by gen and is
80 # called when ever an illegal instruction is encountered
81 ::internal::illegal
82 program_interrupt(processor, cia,
83 illegal_instruction_program_interrupt);
84 return 0;
85
86
87 # The following (floating point unavailable) instruction is `known' by gen
88 # and is called when ever an a floating point instruction is to be
89 # executed but floating point is make unavailable by the MSR
90 ::internal::floating_point_unavailable
91 floating_point_unavailable_interrupt(processor, cia);
92 return 0;
93
94
95 #
96 # Floating point support functions
97 #
98
99 # Convert 32bit single to 64bit double
100 unsigned64::function::DOUBLE:unsigned32 WORD
101 unsigned64 FRT;
102 if (EXTRACTED32(WORD, 1, 8) > 0
103 && EXTRACTED32(WORD, 1, 8) < 255) {
104 /* normalized operand */
105 int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/
106 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
107 | INSERTED64(not_word_1_1, 2, 2)
108 | INSERTED64(not_word_1_1, 3, 3)
109 | INSERTED64(not_word_1_1, 4, 4)
110 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
111 }
112 else if (EXTRACTED32(WORD, 1, 8) == 0
113 && EXTRACTED32(WORD, 9, 31) != 0) {
114 /* denormalized operand */
115 int sign = EXTRACTED32(WORD, 0, 0);
116 int exp = -126;
117 unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29));
118 /* normalize the operand */
119 while (MASKED64(frac, 0, 0) == 0) {
120 frac <<= 1;
121 exp -= 1;
122 }
123 FRT = (INSERTED64(sign, 0, 0)
124 | INSERTED64(exp + 1023, 1, 11)
125 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
126 }
127 else if (EXTRACTED32(WORD, 1, 8) == 255
128 || EXTRACTED32(WORD, 1, 31) == 0) {
129 FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1)
130 | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2)
131 | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3)
132 | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4)
133 | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29)));
134 }
135 else {
136 error("DOUBLE - unknown case\n");
137 FRT = 0;
138 }
139 return FRT;
140
141 # Convert 64bit single to 32bit double
142 unsigned32::function::SINGLE:unsigned64 FRS
143 unsigned32 WORD;
144 if (EXTRACTED64(FRS, 1, 11) > 896
145 || EXTRACTED64(FRS, 1, 63) == 0) {
146 /* no denormalization required (includes Zero/Infinity/NaN) */
147 WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1)
148 | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31));
149 }
150 else if (874 <= EXTRACTED64(FRS, 1, 11)
151 && EXTRACTED64(FRS, 1, 11) <= 896) {
152 /* denormalization required */
153 int sign = EXTRACTED64(FRS, 0, 0);
154 int exp = EXTRACTED64(FRS, 1, 11) - 1023;
155 unsigned64 frac = (BIT64(0)
156 | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52));
157 /* denormalize the operand */
158 while (exp < -126) {
159 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
160 exp += 1;
161 }
162 WORD = (INSERTED32(sign, 0, 0)
163 | INSERTED32(0x00, 1, 8)
164 | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31));
165 }
166 else {
167 WORD = 0x0; /* ??? */
168 }
169 return WORD;
170
171
172 # round 64bit double to 64bit but single
173 void::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx
174 /* comparisons ignore u bits */
175 unsigned64 out;
176 int inc = 0;
177 int lsb = EXTRACTED64(*frac_grx, 23, 23);
178 int gbit = EXTRACTED64(*frac_grx, 24, 24);
179 int rbit = EXTRACTED64(*frac_grx, 25, 25);
180 int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0;
181 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
182 if (lsb == 1 && gbit == 1) inc = 1;
183 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
184 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
185 }
186 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
187 if (sign == 0 && gbit == 1) inc = 1;
188 if (sign == 0 && rbit == 1) inc = 1;
189 if (sign == 0 && xbit == 1) inc = 1;
190 }
191 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
192 if (sign == 1 && gbit == 1) inc = 1;
193 if (sign == 1 && rbit == 1) inc = 1;
194 if (sign == 1 && xbit == 1) inc = 1;
195 }
196 /* work out addition in low 25 bits of out */
197 out = EXTRACTED64(*frac_grx, 0, 23) + inc;
198 *frac_grx = INSERTED64(out, 0, 23);
199 if (out & BIT64(64 - 23 - 1 - 1)) {
200 *frac_grx = (BIT64(0) |
201 INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23));
202 *exp = *exp + 1;
203 }
204 /* frac_grx[24:52] = 0 already */
205 FPSCR_SET_FR(inc);
206 FPSCR_SET_FI(gbit || rbit || xbit);
207
208
209 #
210 void::function::Round_Integer:cpu *processor, int sign, unsigned64 *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode
211 int inc = 0;
212 if (round_mode == fpscr_rn_round_to_nearest) {
213 if (*frac64 == 1 && gbit == 1) inc = 1;
214 if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1;
215 if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1;
216 }
217 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
218 if (sign == 0 && gbit == 1) inc = 1;
219 if (sign == 0 && rbit == 1) inc = 1;
220 if (sign == 0 && xbit == 1) inc = 1;
221 }
222 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
223 if (sign == 1 && gbit == 1) inc = 1;
224 if (sign == 1 && rbit == 1) inc = 1;
225 if (sign == 1 && xbit == 1) inc = 1;
226 }
227 /* frac[0:64] = frac[0:64} + inc */
228 *frac += (*frac64 && inc ? 1 : 0);
229 *frac64 = (*frac64 + inc) & 0x1;
230 FPSCR_SET_FR(inc);
231 FPSCR_SET_FI(gbit | rbit | xbit);
232
233
234 void::function::Round_Float:cpu *processor, int sign, int *exp, unsigned64 *frac, fpscreg round_mode
235 int carry_out;
236 int inc = 0;
237 int lsb = EXTRACTED64(*frac, 52, 52);
238 int gbit = EXTRACTED64(*frac, 53, 53);
239 int rbit = EXTRACTED64(*frac, 54, 54);
240 int xbit = EXTRACTED64(*frac, 55, 55);
241 if (round_mode == fpscr_rn_round_to_nearest) {
242 if (lsb == 1 && gbit == 1) inc = 1;
243 if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1;
244 if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1;
245 }
246 if (round_mode == fpscr_rn_round_towards_pos_infinity) {
247 if (sign == 0 && gbit == 1) inc = 1;
248 if (sign == 0 && rbit == 1) inc = 1;
249 if (sign == 0 && xbit == 1) inc = 1;
250 }
251 if (round_mode == fpscr_rn_round_towards_neg_infinity) {
252 if (sign == 1 && gbit == 1) inc = 1;
253 if (sign == 1 && rbit == 1) inc = 1;
254 if (sign == 1 && xbit == 1) inc = 1;
255 }
256 /* frac//carry_out = frac + inc */
257 *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1);
258 carry_out = EXTRACTED64(*frac, 0, 0);
259 *frac <<= 1;
260 if (carry_out == 1) *exp = *exp + 1;
261 FPSCR_SET_FR(inc);
262 FPSCR_SET_FI(gbit | rbit | xbit);
263 FPSCR_SET_XX(FPSCR & fpscr_fi);
264
265
266 # conversion of FP to integer
267 void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 frb, fpscreg round_mode, int tgt_precision
268 int i;
269 int exp = 0;
270 unsigned64 frac = 0;
271 int frac64 = 0;
272 int gbit = 0;
273 int rbit = 0;
274 int xbit = 0;
275 int sign = EXTRACTED64(frb, 0, 0);
276 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
277 goto Infinity_Operand;
278 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
279 goto SNaN_Operand;
280 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
281 goto QNaN_Operand;
282 if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand;
283 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
284 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
285 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
286 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
287 frac64 = 0;
288 }
289 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
290 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
291 frac64 = 0;
292 }
293 gbit = 0, rbit = 0, xbit = 0;
294 for (i = 1; i <= 63 - exp; i++) {
295 xbit = rbit | xbit;
296 rbit = gbit;
297 gbit = frac64;
298 frac64 = EXTRACTED64(frac, 63, 63);
299 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
300 }
301 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
302 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
303 frac = ~frac;
304 frac64 ^= 1;
305 frac += (frac64 ? 1 : 0);
306 frac64 = (frac64 + 1) & 0x1;
307 }
308 if (tgt_precision == 32 /* can ignore frac64 in compare */
309 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
310 goto Large_Operand;
311 if (tgt_precision == 64 /* can ignore frac64 in compare */
312 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
313 goto Large_Operand;
314 if (tgt_precision == 32 /* can ignore frac64 in compare */
315 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
316 goto Large_Operand;
317 if (tgt_precision == 64 /* can ignore frac64 in compare */
318 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
319 goto Large_Operand;
320 FPSCR_SET_XX(FPSCR & fpscr_fi);
321 if (tgt_precision == 32)
322 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
323 if (tgt_precision == 64)
324 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
325 /*FPSCR[fprf] = undefined */
326 goto Done;
327 /**/
328 Infinity_Operand:
329 FPSCR_SET_FR(0);
330 FPSCR_SET_FI(0);
331 FPSCR_OR_VX(fpscr_vxcvi);
332 if ((FPSCR & fpscr_ve) == 0) {
333 if (tgt_precision == 32) {
334 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
335 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
336 }
337 else {
338 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
339 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
340 }
341 /* FPSCR[FPRF] = undefined */
342 }
343 goto Done;
344 /**/
345 SNaN_Operand:
346 FPSCR_SET_FR(0);
347 FPSCR_SET_FI(0);
348 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
349 if ((FPSCR & fpscr_ve) == 0) {
350 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
351 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
352 /* FPSCR[fprf] = undefined */
353 }
354 goto Done;
355 /**/
356 QNaN_Operand:
357 FPSCR_SET_FR(0);
358 FPSCR_SET_FI(0);
359 FPSCR_OR_VX(fpscr_vxcvi);
360 if ((FPSCR & fpscr_ve) == 0) {
361 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
362 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
363 /* FPSCR[fprf] = undefined */
364 }
365 goto Done;
366 /**/
367 Large_Operand:
368 FPSCR_SET_FR(0);
369 FPSCR_SET_FI(0);
370 FPSCR_OR_VX(fpscr_vxcvi);
371 if ((FPSCR & fpscr_ve) == 0) {
372 if (tgt_precision == 32) {
373 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
374 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
375 }
376 else {
377 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
378 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
379 }
380 /* FPSCR[fprf] = undefined */
381 }
382 /**/
383 Done:
384
385
386 # extract out raw fields of a FP number
387 int::function::sign:unsigned64 FRS
388 return (MASKED64(FRS, 0, 0)
389 ? -1
390 : 1);
391 int::function::biased_exp:unsigned64 frs, int single
392 if (single)
393 return EXTRACTED64(frs, 1, 8);
394 else
395 return EXTRACTED64(frs, 1, 11);
396 unsigned64::function::fraction:unsigned64 frs, int single
397 if (single)
398 return EXTRACTED64(frs, 9, 31);
399 else
400 return EXTRACTED64(frs, 12, 63);
401
402 # a number?, each of the below return +1 or -1 (based on sign bit)
403 # if true.
404 int::function::is_nor:unsigned64 frs, int single
405 int exp = biased_exp(frs, single);
406 return (exp >= 1
407 && exp <= (single ? 254 : 2046));
408 int::function::is_zero:unsigned64 FRS
409 return (MASKED64(FRS, 1, 63) == 0
410 ? sign(FRS)
411 : 0);
412 int::function::is_den:unsigned64 frs, int single
413 int exp = biased_exp(frs, single);
414 unsigned64 frac = fraction(frs, single);
415 return (exp == 0 && frac != 0
416 ? sign(frs)
417 : 0);
418 int::function::is_inf:unsigned64 frs, int single
419 int exp = biased_exp(frs, single);
420 int frac = fraction(frs, single);
421 return (exp == (single ? 255 : 2047) && frac == 0
422 ? sign(frs)
423 : 0);
424 int::function::is_NaN:unsigned64 frs, int single
425 int exp = biased_exp(frs, single);
426 int frac = fraction(frs, single);
427 return (exp == (single ? 255 : 2047) && frac != 0
428 ? sign(frs)
429 : 0);
430 int::function::is_SNaN:unsigned64 frs, int single
431 return (is_NaN(frs, single)
432 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
433 ? sign(frs)
434 : 0);
435 int::function::is_QNaN:unsigned64 frs, int single
436 return (is_NaN(frs, single) && !is_SNaN(frs, single));
437 int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
438 return *(double*)fra < *(double*)frb;
439 int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
440 return *(double*)fra > *(double*)frb;
441 int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
442 return *(double*)fra == *(double*)frb;
443
444
445 # which quiet nan should become the result
446 unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
447 unsigned64 frt = 0;
448 if (is_NaN(fra, single))
449 frt = fra;
450 else if (is_NaN(frb, single))
451 if (instruction_is_frsp)
452 frt = MASKED64(frb, 0, 34);
453 else
454 frt = frb;
455 else if (is_NaN(frc, single))
456 frt = frc;
457 else if (generate_qnan)
458 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
459 else
460 error("select_qnan - default reached\n");
461 return frt;
462
463
464 # detect invalid operation
465 int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
466 int fail = 0;
467 if ((check & fpscr_vxsnan)
468 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
469 FPSCR_OR_VX(fpscr_vxsnan);
470 fail = 1;
471 }
472 if ((check & fpscr_vxisi)
473 && (is_inf(fra, single) && is_inf(frb, single))
474 && ((negate && sign(fra) != sign(frb))
475 || (!negate && sign(fra) == sign(frb)))) {
476 /*FIXME: don't handle inf-inf VS inf+-inf */
477 FPSCR_OR_VX(fpscr_vxisi);
478 fail = 1;
479 }
480 if ((check & fpscr_vxidi)
481 && (is_inf(fra, single) && is_inf(frb, single))) {
482 FPSCR_OR_VX(fpscr_vxidi);
483 fail = 1;
484 }
485 if ((check & fpscr_vxzdz)
486 && (is_zero(fra) && is_zero(frb))) {
487 FPSCR_OR_VX(fpscr_vxzdz);
488 fail = 1;
489 }
490 if ((check & fpscr_vximz)
491 && (is_zero(fra) && is_inf(frb, single))) {
492 FPSCR_OR_VX(fpscr_vximz);
493 fail = 1;
494 }
495 if ((check & fpscr_vxvc)
496 && (is_NaN(fra, single) || is_NaN(frb, single))) {
497 FPSCR_OR_VX(fpscr_vxvc);
498 fail = 1;
499 }
500 if ((check & fpscr_vxsoft)) {
501 FPSCR_OR_VX(fpscr_vxsoft);
502 fail = 1;
503 }
504 if ((check & fpscr_vxsqrt)
505 && sign(fra) < 0) {
506 FPSCR_OR_VX(fpscr_vxsqrt);
507 fail = 1;
508 }
509 /* if ((check && fpscr_vxcvi) {
510 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
511 FPSCR_OR_VX(fpscr_vxcvi);
512 fail = 1;
513 }
514 */
515 return fail;
516
517
518
519
520
521 # handle case of invalid operation
522 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
523 if (FPSCR & fpscr_ve) {
524 /* invalid operation exception enabled */
525 /* FRT unchaged */
526 FPSCR_SET_FR(0);
527 FPSCR_SET_FI(0);
528 /* fpscr_FPRF unchanged */
529 }
530 else {
531 /* invalid operation exception disabled */
532 if (instruction_is_convert_to_64bit) {
533 error("oopsi");
534 }
535 else if (instruction_is_convert_to_32bit) {
536 error("oopsi");
537 }
538 else { /* arrith, frsp */
539 *frt = select_qnan(fra, frb, frc,
540 instruction_is_frsp, 0/*generate*/, single);
541 FPSCR_SET_FR(0);
542 FPSCR_SET_FI(0);
543 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
544 }
545 }
546
547
548
549
550 #
551 # I.2.4.1 Branch Instructions
552 #
553 0.18,6.LI,30.AA,31.LK:I:t::Branch
554 *PPC603:PPC603_BPU:1:1:0
555 *PPC603e:PPC603_BPU:1:1:0
556 *PPC604:PPC603_BPU:1:1:0
557 if (AA) NIA = IEA(EXTS(LI_0b00));
558 else NIA = IEA(CIA + EXTS(LI_0b00));
559 if (LK) LR = (spreg)CIA+4;
560 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
561 *PPC603:PPC603_BPU:1:1:0
562 *PPC603e:PPC603_BPU:1:1:0
563 *PPC604:PPC603_BPU:1:1:0
564 int M, ctr_ok, cond_ok;
565 if (is_64bit_implementation && is_64bit_mode) M = 0;
566 else M = 32;
567 if (!BO{2}) CTR = CTR - 1;
568 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
569 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
570 if (ctr_ok && cond_ok)
571 if (AA) NIA = IEA(EXTS(BD_0b00));
572 else NIA = IEA(CIA + EXTS(BD_0b00));
573 if (LK) LR = (spreg)IEA(CIA + 4);
574 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
575 *PPC603:PPC603_BPU:1:1:0
576 *PPC603e:PPC603_BPU:1:1:0
577 *PPC604:PPC603_BPU:1:1:0
578 int M, ctr_ok, cond_ok;
579 if (is_64bit_implementation && is_64bit_mode) M = 0;
580 else M = 32;
581 if (!BO{2}) CTR = CTR - 1;
582 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
583 cond_ok = BO{0} || (CR{BI} == BO{1});
584 if (ctr_ok && cond_ok) NIA = IEA(LR_0b00);
585 if (LK) LR = (spreg)IEA(CIA + 4);
586 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
587 *PPC603:PPC603_BPU:1:1:0
588 *PPC603e:PPC603_BPU:1:1:0
589 *PPC604:PPC603_BPU:1:1:0
590 int cond_ok;
591 cond_ok = BO{0} || (CR{BI} == BO{1});
592 if (cond_ok) NIA = IEA(CTR_0b00);
593 if (LK) LR = (spreg)IEA(CIA + 4);
594
595 #
596 # I.2.4.2 System Call Instruction
597 #
598 0.17,6./,11./,16./,30.1,31./:SC:t::System Call
599 system_call_interrupt(processor, cia);
600
601 #
602 # I.2.4.3 Condition Register Logical Instructions
603 #
604 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
605 BLIT32(CR, BT, CR{BA} && CR{BB});
606 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
607 BLIT32(CR, BT, CR{BA} || CR{BB});
608 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
609 BLIT32(CR, BT, CR{BA} != CR{BB});
610 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
611 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
612 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
613 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
614 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
615 BLIT32(CR, BT, CR{BA} == CR{BB});
616 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
617 BLIT32(CR, BT, CR{BA} && !CR{BB});
618 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
619 BLIT32(CR, BT, CR{BA} || !CR{BB});
620
621 #
622 # I.2.4.4 Condition Register Field Instruction
623 #
624 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
625 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
626
627
628 #
629 # I.3.3.2 Fixed-Point Load Instructions
630 #
631
632 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
633 unsigned_word b;
634 unsigned_word EA;
635 if (RA == 0) b = 0;
636 else b = *rA;
637 EA = b + EXTS(D);
638 *rT = MEM(unsigned, EA, 1);
639 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
640 unsigned_word b;
641 unsigned_word EA;
642 if (RA == 0) b = 0;
643 else b = *rA;
644 EA = b + *rB;
645 *rT = MEM(unsigned, EA, 1);
646 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
647 unsigned_word EA;
648 if (RA == 0 || RA == RT)
649 program_interrupt(processor, cia,
650 illegal_instruction_program_interrupt);
651 EA = *rA + EXTS(D);
652 *rT = MEM(unsigned, EA, 1);
653 *rA = EA;
654 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
655 unsigned_word EA;
656 if (RA == 0 || RA == RT)
657 program_interrupt(processor, cia,
658 illegal_instruction_program_interrupt);
659 EA = *rA + *rB;
660 *rT = MEM(unsigned, EA, 1);
661 *rA = EA;
662
663 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
664 unsigned_word b;
665 unsigned_word EA;
666 if (RA == 0) b = 0;
667 else b = *rA;
668 EA = b + EXTS(D);
669 *rT = MEM(unsigned, EA, 2);
670 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
671 unsigned_word b;
672 unsigned_word EA;
673 if (RA == 0) b = 0;
674 else b = *rA;
675 EA = b + *rB;
676 *rT = MEM(unsigned, EA, 2);
677 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
678 unsigned_word EA;
679 if (RA == 0 || RA == RT)
680 program_interrupt(processor, cia,
681 illegal_instruction_program_interrupt);
682 EA = *rA + EXTS(D);
683 *rT = MEM(unsigned, EA, 2);
684 *rA = EA;
685 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
686 unsigned_word EA;
687 if (RA == 0 || RA == RT)
688 program_interrupt(processor, cia,
689 illegal_instruction_program_interrupt);
690 EA = *rA + *rB;
691 *rT = MEM(unsigned, EA, 2);
692 *rA = EA;
693
694 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
695 unsigned_word b;
696 unsigned_word EA;
697 if (RA == 0) b = 0;
698 else b = *rA;
699 EA = b + EXTS(D);
700 *rT = MEM(signed, EA, 2);
701 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
702 unsigned_word b;
703 unsigned_word EA;
704 if (RA == 0) b = 0;
705 else b = *rA;
706 EA = b + *rB;
707 *rT = MEM(signed, EA, 2);
708 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
709 unsigned_word EA;
710 if (RA == 0 || RA == RT)
711 program_interrupt(processor, cia,
712 illegal_instruction_program_interrupt);
713 EA = *rA + EXTS(D);
714 *rT = MEM(signed, EA, 2);
715 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
716 unsigned_word EA;
717 if (RA == 0 || RA == RT)
718 program_interrupt(processor, cia,
719 illegal_instruction_program_interrupt);
720 EA = *rA + *rB;
721 *rT = MEM(signed, EA, 2);
722 *rA = EA;
723
724 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero
725 unsigned_word b;
726 unsigned_word EA;
727 if (RA == 0) b = 0;
728 else b = *rA;
729 EA = b + EXTS(D);
730 *rT = MEM(unsigned, EA, 4);
731 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
732 unsigned_word b;
733 unsigned_word EA;
734 if (RA == 0) b = 0;
735 else b = *rA;
736 EA = b + *rB;
737 *rT = MEM(unsigned, EA, 4);
738 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
739 unsigned_word EA;
740 if (RA == 0 || RA == RT)
741 program_interrupt(processor, cia,
742 illegal_instruction_program_interrupt);
743 EA = *rA + EXTS(D);
744 *rT = MEM(unsigned, EA, 4);
745 *rA = EA;
746 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
747 unsigned_word EA;
748 if (RA == 0 || RA == RT)
749 program_interrupt(processor, cia,
750 illegal_instruction_program_interrupt);
751 EA = *rA + *rB;
752 *rT = MEM(unsigned, EA, 4);
753 *rA = EA;
754
755 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
756 # unsigned_word b;
757 # unsigned_word EA;
758 # if (RA == 0) b = 0;
759 # else b = *rA;
760 # EA = b + EXTS(DS_0b00);
761 # *rT = MEM(signed, EA, 4);
762 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
763 # unsigned_word b;
764 # unsigned_word EA;
765 # if (RA == 0) b = 0;
766 # else b = *rA;
767 # EA = b + *rB;;
768 # *rT = MEM(signed, EA, 4);
769 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
770 # unsigned_word EA;
771 # if (RA == 0 || RA == RT)
772 # program_interrupt(processor, cia
773 # illegal_instruction_program_interrupt);
774 # EA = *rA + *rB;
775 # *rT = MEM(signed, EA, 4);
776 # *rA = EA;
777
778 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
779 # unsigned_word b;
780 # unsigned_word EA;
781 # if (RA == 0) b = 0;
782 # else b = *rA;
783 # EA = b + EXTS(DS_0b00);
784 # *rT = MEM(unsigned, EA, 8);
785 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
786 # unsigned_word b;
787 # unsigned_word EA;
788 # if (RA == 0) b = 0;
789 # else b = *rA;
790 # EA = b + *rB;
791 # *rT = MEM(unsigned, EA, 8);
792 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
793 # unsigned_word EA;
794 # if (RA == 0 || RA == RT)
795 # program_interrupt(processor, cia
796 # illegal_instruction_program_interrupt);
797 # EA = *rA + EXTS(DS_0b00);
798 # *rT = MEM(unsigned, EA, 8);
799 # *rA = EA;
800 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
801 # unsigned_word EA;
802 # if (RA == 0 || RA == RT)
803 # program_interrupt(processor, cia
804 # illegal_instruction_program_interrupt);
805 # EA = *rA + *rB;
806 # *rT = MEM(unsigned, EA, 8);
807 # *rA = EA;
808
809
810
811 #
812 # I.3.3.3 Fixed-Point Store Instructions
813 #
814
815 0.38,6.RS,11.RA,16.D:D:::Store Byte
816 unsigned_word b;
817 unsigned_word EA;
818 if (RA == 0) b = 0;
819 else b = *rA;
820 EA = b + EXTS(D);
821 STORE(EA, 1, *rS);
822 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
823 unsigned_word b;
824 unsigned_word EA;
825 if (RA == 0) b = 0;
826 else b = *rA;
827 EA = b + *rB;
828 STORE(EA, 1, *rS);
829 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update
830 unsigned_word EA;
831 if (RA == 0)
832 program_interrupt(processor, cia,
833 illegal_instruction_program_interrupt);
834 EA = *rA + EXTS(D);
835 STORE(EA, 1, *rS);
836 *rA = EA;
837 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
838 unsigned_word EA;
839 if (RA == 0)
840 program_interrupt(processor, cia,
841 illegal_instruction_program_interrupt);
842 EA = *rA + *rB;
843 STORE(EA, 1, *rS);
844 *rA = EA;
845
846 0.44,6.RS,11.RA,16.D:D:::Store Half Word
847 unsigned_word b;
848 unsigned_word EA;
849 if (RA == 0) b = 0;
850 else b = *rA;
851 EA = b + EXTS(D);
852 STORE(EA, 2, *rS);
853 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
854 unsigned_word b;
855 unsigned_word EA;
856 if (RA == 0) b = 0;
857 else b = *rA;
858 EA = b + *rB;
859 STORE(EA, 2, *rS);
860 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
861 unsigned_word EA;
862 if (RA == 0)
863 program_interrupt(processor, cia,
864 illegal_instruction_program_interrupt);
865 EA = *rA + EXTS(D);
866 STORE(EA, 2, *rS);
867 *rA = EA;
868 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
869 unsigned_word EA;
870 if (RA == 0)
871 program_interrupt(processor, cia,
872 illegal_instruction_program_interrupt);
873 EA = *rA + *rB;
874 STORE(EA, 2, *rS);
875 *rA = EA;
876
877 0.36,6.RS,11.RA,16.D:D:::Store Word
878 unsigned_word b;
879 unsigned_word EA;
880 if (RA == 0) b = 0;
881 else b = *rA;
882 EA = b + EXTS(D);
883 STORE(EA, 4, *rS);
884 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
885 unsigned_word b;
886 unsigned_word EA;
887 if (RA == 0) b = 0;
888 else b = *rA;
889 EA = b + *rB;
890 STORE(EA, 4, *rS);
891 0.37,6.RS,11.RA,16.D:D:::Store Word with Update
892 unsigned_word EA;
893 if (RA == 0)
894 program_interrupt(processor, cia,
895 illegal_instruction_program_interrupt);
896 EA = *rA + EXTS(D);
897 STORE(EA, 4, *rS);
898 *rA = EA;
899 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
900 unsigned_word EA;
901 if (RA == 0)
902 program_interrupt(processor, cia,
903 illegal_instruction_program_interrupt);
904 EA = *rA + *rB;
905 STORE(EA, 4, *rS);
906 *rA = EA;
907
908 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
909 # unsigned_word b;
910 # unsigned_word EA;
911 # if (RA == 0) b = 0;
912 # else b = *rA;
913 # EA = b + EXTS(DS_0b00);
914 # STORE(EA, 8, *rS);
915 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
916 # unsigned_word b;
917 # unsigned_word EA;
918 # if (RA == 0) b = 0;
919 # else b = *rA;
920 # EA = b + *rB;
921 # STORE(EA, 8, *rS);
922 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
923 # unsigned_word EA;
924 # if (RA == 0)
925 # program_interrupt(processor, cia
926 # illegal_instruction_program_interrupt);
927 # EA = *rA + EXTS(DS_0b00);
928 # STORE(EA, 8, *rS);
929 # *rA = EA;
930 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
931 # unsigned_word EA;
932 # if (RA == 0)
933 # program_interrupt(processor, cia
934 # illegal_instruction_program_interrupt);
935 # EA = *rA + *rB;
936 # STORE(EA, 8, *rS);
937 # *rA = EA;
938
939
940 #
941 # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
942 #
943
944 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
945 unsigned_word b;
946 unsigned_word EA;
947 if (RA == 0) b = 0;
948 else b = *rA;
949 EA = b + *rB;
950 *rT = SWAP_2(MEM(unsigned, EA, 2));
951 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
952 unsigned_word b;
953 unsigned_word EA;
954 if (RA == 0) b = 0;
955 else b = *rA;
956 EA = b + *rB;
957 *rT = SWAP_4(MEM(unsigned, EA, 4));
958
959 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
960 unsigned_word b;
961 unsigned_word EA;
962 if (RA == 0) b = 0;
963 else b = *rA;
964 EA = b + *rB;
965 STORE(EA, 2, SWAP_2(*rS));
966 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
967 unsigned_word b;
968 unsigned_word EA;
969 if (RA == 0) b = 0;
970 else b = *rA;
971 EA = b + *rB;
972 STORE(EA, 4, SWAP_4(*rS));
973
974
975 #
976 # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
977 #
978
979 0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
980 0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
981
982
983 #
984 # I.3.3.6 Fixed-Point Move Assist Instructions
985 #
986
987 0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
988 0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
989
990 0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
991 0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
992
993
994 #
995 # I.3.3.7 Storage Synchronization Instructions
996 #
997 # HACK: Rather than monitor addresses looking for a reason
998 # to cancel a reservation. This code instead keeps
999 # a copy of the data read from memory. Before performing
1000 # a store, the memory area is checked to see if it has
1001 # been changed.
1002 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
1003 unsigned_word b;
1004 unsigned_word EA;
1005 if (RA == 0) b = 0;
1006 else b = *rA;
1007 EA = b + *rB;
1008 RESERVE = 1;
1009 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1010 RESERVE_DATA = MEM(unsigned, EA, 4);
1011 *rT = RESERVE_DATA;
1012 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
1013 unsigned_word b;
1014 unsigned_word EA;
1015 if (RA == 0) b = 0;
1016 else b = *rA;
1017 EA = b + *rB;
1018 RESERVE = 1;
1019 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
1020 RESERVE_DATA = MEM(unsigned, EA, 8);
1021 *rT = RESERVE_DATA;
1022
1023 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
1024 unsigned_word b;
1025 unsigned_word EA;
1026 if (RA == 0) b = 0;
1027 else b = *rA;
1028 EA = b + *rB;
1029 if (RESERVE) {
1030 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1031 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
1032 STORE(EA, 4, *rS);
1033 CR_SET_XER_SO(0, cr_i_zero);
1034 }
1035 else {
1036 /* ment to randomly to store, we never do! */
1037 CR_SET_XER_SO(0, 0);
1038 }
1039 RESERVE = 0;
1040 }
1041 else {
1042 CR_SET_XER_SO(0, 0);
1043 }
1044 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
1045 unsigned_word b;
1046 unsigned_word EA;
1047 if (RA == 0) b = 0;
1048 else b = *rA;
1049 EA = b + *rB;
1050 if (RESERVE) {
1051 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
1052 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
1053 STORE(EA, 8, *rS);
1054 CR_SET_XER_SO(0, cr_i_zero);
1055 }
1056 else {
1057 /* ment to randomly to store, we never do */
1058 CR_SET_XER_SO(0, 0);
1059 }
1060 RESERVE = 0;
1061 }
1062 else {
1063 CR_SET_XER_SO(0, 0);
1064 }
1065
1066 0.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
1067 /* do nothing */
1068
1069
1070 #
1071 # I.3.3.9 Fixed-Point Arithmetic Instructions
1072 #
1073
1074 0.14,6.RT,11.RA,16.SI:D:T::Add Immediate
1075 *PPC603:PPC603_IU:1:1:0
1076 *PPC603e:PPC603e_IU|PPC603e_SRU:1:1:0
1077 *PPC604:PPC604_SCIU:1:1:0
1078 if (RA_is_0) *rT = EXTS(SI);
1079 else *rT = *rA + EXTS(SI);
1080 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
1081 if (RA_is_0) *rT = EXTS(SI) << 16;
1082 else *rT = *rA + (EXTS(SI) << 16);
1083 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
1084 ALU_BEGIN(*rA);
1085 ALU_ADD(*rB);
1086 ALU_END(*rT, 0/*CA*/, OE, Rc);
1087 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
1088 ALU_BEGIN(*rA);
1089 ALU_NOT;
1090 ALU_ADD(*rB);
1091 ALU_ADD(1);
1092 ALU_END(*rT, 0/*CA*/, OE, Rc);
1093 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
1094 ALU_BEGIN(*rA);
1095 ALU_ADD(EXTS(SI));
1096 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1097 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
1098 ALU_BEGIN(*rA);
1099 ALU_ADD(EXTS(SI));
1100 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
1101 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
1102 ALU_BEGIN(*rA);
1103 ALU_NOT;
1104 ALU_ADD(EXTS(SI));
1105 ALU_ADD(1);
1106 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
1107 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
1108 ALU_BEGIN(*rA);
1109 ALU_ADD(*rB);
1110 ALU_END(*rT, 1/*CA*/, OE, Rc);
1111 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
1112 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
1113 ALU_BEGIN(*rA);
1114 ALU_NOT;
1115 ALU_ADD(*rB);
1116 ALU_ADD(1);
1117 ALU_END(*rT, 1/*CA*/, OE, Rc);
1118 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
1119 ALU_BEGIN(*rA);
1120 ALU_ADD(*rB);
1121 ALU_ADD_CA;
1122 ALU_END(*rT, 1/*CA*/, OE, Rc);
1123 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
1124 ALU_BEGIN(*rA);
1125 ALU_NOT;
1126 ALU_ADD(*rB);
1127 ALU_ADD_CA;
1128 ALU_END(*rT, 1/*CA*/, OE, Rc);
1129 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
1130 # ALU_BEGIN(*rA);
1131 # ALU_ADD_CA;
1132 # ALU_SUB(1);
1133 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1134 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
1135 # ALU_BEGIN(*rA);
1136 # ALU_NOT;
1137 # ALU_ADD_CA;
1138 # ALU_SUB(1);
1139 # ALU_END(*rT, 1/*CA*/, OE, Rc);
1140 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
1141 ALU_BEGIN(*rA);
1142 ALU_ADD_CA;
1143 ALU_END(*rT, 1/*CA*/, OE, Rc);
1144 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
1145 ALU_BEGIN(*rA);
1146 ALU_NOT;
1147 ALU_ADD_CA;
1148 ALU_END(*rT, 1/*CA*/, OE, Rc);
1149 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
1150 ALU_BEGIN(*rA);
1151 ALU_NOT;
1152 ALU_ADD(1);
1153 ALU_END(*rT,0/*CA*/,OE,Rc);
1154 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
1155 signed_word prod = *rA * EXTS(SI);
1156 *rT = prod;
1157 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
1158 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
1159 signed64 a = (signed32)(*rA);
1160 signed64 b = (signed32)(*rB);
1161 signed64 prod = a * b;
1162 signed_word t = prod;
1163 *rT = *rA * *rB;
1164 if (t != prod && OE)
1165 XER |= (xer_overflow | xer_summary_overflow);
1166 CR0_COMPARE(t, 0, Rc);
1167 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
1168 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
1169 signed64 a = (signed32)(*rA);
1170 signed64 b = (signed32)(*rB);
1171 signed64 prod = a * b;
1172 signed_word t = EXTRACTED64(prod, 0, 31);
1173 *rT = t;
1174 CR0_COMPARE(t, 0, Rc);
1175 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
1176 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
1177 unsigned64 a = (unsigned32)(*rA);
1178 unsigned64 b = (unsigned32)(*rB);
1179 unsigned64 prod = a * b;
1180 signed_word t = EXTRACTED64(prod, 0, 31);
1181 *rT = t;
1182 CR0_COMPARE(t, 0, Rc);
1183 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
1184 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
1185 signed64 dividend = (signed32)(*rA);
1186 signed64 divisor = (signed32)(*rB);
1187 if (divisor == 0 /* nb 0x8000..0 is sign extended */
1188 || (dividend == 0x80000000 && divisor == -1)) {
1189 if (OE)
1190 XER |= (xer_overflow | xer_summary_overflow);
1191 CR0_COMPARE(0, 0, Rc);
1192 }
1193 else {
1194 signed64 quotent = dividend / divisor;
1195 *rT = quotent;
1196 CR0_COMPARE((signed_word)quotent, 0, Rc);
1197 }
1198 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
1199 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
1200 unsigned64 dividend = (unsigned32)(*rA);
1201 unsigned64 divisor = (unsigned32)(*rB);
1202 if (divisor == 0) {
1203 if (OE)
1204 XER |= (xer_overflow | xer_summary_overflow);
1205 CR0_COMPARE(0, 0, Rc);
1206 }
1207 else {
1208 unsigned64 quotent = dividend / divisor;
1209 *rT = quotent;
1210 CR0_COMPARE((signed_word)quotent, 0, Rc);
1211 }
1212
1213
1214 #
1215 # I.3.3.10 Fixed-Point Compare Instructions
1216 #
1217
1218 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
1219 if (!is_64bit_mode && L)
1220 program_interrupt(processor, cia,
1221 illegal_instruction_program_interrupt);
1222 else {
1223 signed_word a;
1224 signed_word b = EXTS(SI);
1225 if (L == 0)
1226 a = EXTENDED(*rA);
1227 else
1228 a = *rA;
1229 CR_COMPARE(BF, a, b);
1230 }
1231 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
1232 if (!is_64bit_mode && L)
1233 program_interrupt(processor, cia,
1234 illegal_instruction_program_interrupt);
1235 else {
1236 signed_word a;
1237 signed_word b;
1238 if (L == 0) {
1239 a = EXTENDED(*rA);
1240 b = EXTENDED(*rB);
1241 }
1242 else {
1243 a = *rA;
1244 b = *rB;
1245 }
1246 CR_COMPARE(BF, a, b);
1247 }
1248 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
1249 if (!is_64bit_mode && L)
1250 program_interrupt(processor, cia,
1251 illegal_instruction_program_interrupt);
1252 else {
1253 unsigned_word a;
1254 unsigned_word b = UI;
1255 if (L == 0)
1256 a = MASKED(*rA, 32, 63);
1257 else
1258 a = *rA;
1259 CR_COMPARE(BF, a, b);
1260 }
1261 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
1262 if (!is_64bit_mode && L)
1263 program_interrupt(processor, cia,
1264 illegal_instruction_program_interrupt);
1265 else {
1266 unsigned_word a;
1267 unsigned_word b;
1268 if (L == 0) {
1269 a = MASKED(*rA, 32, 63);
1270 b = MASKED(*rB, 32, 63);
1271 }
1272 else {
1273 a = *rA;
1274 b = *rB;
1275 }
1276 CR_COMPARE(BF, a, b);
1277 }
1278
1279
1280 #
1281 # I.3.3.11 Fixed-Point Trap Instructions
1282 #
1283
1284 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
1285 if (!is_64bit_mode)
1286 program_interrupt(processor, cia,
1287 illegal_instruction_program_interrupt);
1288 else {
1289 signed_word a = *rA;
1290 signed_word b = EXTS(SI);
1291 if ((a < b && TO{0})
1292 || (a > b && TO{1})
1293 || (a == b && TO{2})
1294 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1295 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1296 )
1297 program_interrupt(processor, cia,
1298 trap_program_interrupt);
1299 }
1300 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
1301 signed_word a = EXTENDED(*rA);
1302 signed_word b = EXTS(SI);
1303 if ((a < b && TO{0})
1304 || (a > b && TO{1})
1305 || (a == b && TO{2})
1306 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1307 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1308 )
1309 program_interrupt(processor, cia,
1310 trap_program_interrupt);
1311 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
1312 if (!is_64bit_mode)
1313 program_interrupt(processor, cia,
1314 illegal_instruction_program_interrupt);
1315 else {
1316 signed_word a = *rA;
1317 signed_word b = *rB;
1318 if ((a < b && TO{0})
1319 || (a > b && TO{1})
1320 || (a == b && TO{2})
1321 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1322 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1323 )
1324 program_interrupt(processor, cia,
1325 trap_program_interrupt);
1326 }
1327 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
1328 signed_word a = EXTENDED(*rA);
1329 signed_word b = EXTENDED(*rB);
1330 if (TO == 12 && rA == rB) {
1331 ITRACE(trace_breakpoint, ("breakpoint\n"));
1332 cpu_halt(processor, cia, was_trap, 0);
1333 }
1334 else if ((a < b && TO{0})
1335 || (a > b && TO{1})
1336 || (a == b && TO{2})
1337 || ((unsigned_word)a < (unsigned_word)b && TO{3})
1338 || ((unsigned_word)a > (unsigned_word)b && TO{4})
1339 )
1340 program_interrupt(processor, cia,
1341 trap_program_interrupt);
1342
1343 #
1344 # I.3.3.12 Fixed-Point Logical Instructions
1345 #
1346
1347 0.28,6.RS,11.RA,16.UI:D:::AND Immediate
1348 *rA = *rS & UI;
1349 CR0_COMPARE(*rA, 0, 1/*Rc*/);
1350 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
1351 *rA = *rS & (UI << 16);
1352 CR0_COMPARE(*rA, 0, 1/*Rc*/);
1353 0.24,6.RS,11.RA,16.UI:D:::OR Immediate
1354 *rA = *rS | UI;
1355 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
1356 *rA = *rS | (UI << 16);
1357 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate
1358 *rA = *rS ^ UI;
1359 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
1360 *rA = *rS ^ (UI << 16);
1361 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
1362 *rA = *rS & *rB;
1363 CR0_COMPARE(*rA, 0, Rc);
1364 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
1365 *rA = *rS | *rB;
1366 CR0_COMPARE(*rA, 0, Rc);
1367 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
1368 *rA = *rS ^ *rB;
1369 CR0_COMPARE(*rA, 0, Rc);
1370 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
1371 *rA = ~(*rS & *rB);
1372 CR0_COMPARE(*rA, 0, Rc);
1373 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
1374 *rA = ~(*rS | *rB);
1375 CR0_COMPARE(*rA, 0, Rc);
1376 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
1377 # *rA = ~(*rS ^ *rB); /* A === B */
1378 # CR0_COMPARE(*rA, 0, Rc);
1379 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
1380 *rA = *rS & ~*rB;
1381 CR0_COMPARE(*rA, 0, Rc);
1382 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
1383 *rA = *rS | ~*rB;
1384 CR0_COMPARE(*rA, 0, Rc);
1385 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
1386 *rA = (signed_word)(signed8)*rS;
1387 CR0_COMPARE(*rA, 0, Rc);
1388 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
1389 *rA = (signed_word)(signed16)*rS;
1390 CR0_COMPARE(*rA, 0, Rc);
1391 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
1392 # *rA = (signed_word)(signed32)*rS;
1393 # CR0_COMPARE(*rA, 0, Rc);
1394 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
1395 # int count = 0;
1396 # unsigned64 mask = BIT64(0);
1397 # unsigned64 source = *rS;
1398 # while (!(source & mask) && mask != 0) {
1399 # mask >>= 1;
1400 # count++;
1401 # }
1402 # *rA = count;
1403 # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
1404 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
1405 int count = 0;
1406 unsigned32 mask = BIT32(0);
1407 unsigned32 source = *rS;
1408 while (!(source & mask) && mask != 0) {
1409 mask >>= 1;
1410 count++;
1411 }
1412 *rA = count;
1413 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
1414
1415
1416 #
1417 # I.3.3.13 Fixed-Point Rotate and Shift Instructions
1418 #
1419
1420 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
1421 # long n = (sh_5 << 4) | sh_0_4;
1422 # unsigned_word r = ROTL64(*rS, n);
1423 # long b = (mb_5 << 4) | mb_0_4;
1424 # unsigned_word m = MASK(b, 63);
1425 # signed_word result = r & m;
1426 # *rA = result;
1427 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
1428 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
1429 # long n = (sh_5 << 4) | sh_0_4;
1430 # unsigned_word r = ROTL64(*rS, n);
1431 # long e = (me_5 << 4) | me_0_4;
1432 # unsigned_word m = MASK(0, e);
1433 # signed_word result = r & m;
1434 # *rA = result;
1435 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
1436 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
1437 # long n = (sh_5 << 4) | sh_0_4;
1438 # unsigned_word r = ROTL64(*rS, n);
1439 # long b = (mb_5 << 4) | mb_0_4;
1440 # unsigned_word m = MASK(0, (64-n));
1441 # signed_word result = r & m;
1442 # *rA = result;
1443 # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
1444
1445 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
1446 long n = SH;
1447 unsigned32 s = *rS;
1448 unsigned32 r = ROTL32(s, n);
1449 unsigned32 m = MASK(MB+32, ME+32);
1450 signed_word result = r & m;
1451 *rA = result;
1452 CR0_COMPARE(result, 0, Rc);
1453 ITRACE(trace_alu,
1454 ("n=%d, s=0x%x, r=0x%x, m=0x%x, result=0x%x, cr=0x%x\n",
1455 n, s, r, m, result, CR));
1456
1457 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
1458 # long n = MASKED(*rB, 58, 63);
1459 # unsigned_word r = ROTL64(*rS, n);
1460 # long b = (mb_5 << 4) | mb_0_4;
1461 # unsigned_word m = MASK(b, 63);
1462 # signed_word result = r & m;
1463 # *rA = result;
1464 # CR0_COMPARE(result, 0, Rc);
1465 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
1466 # long n = MASKED(*rB, 58, 63);
1467 # unsigned_word r = ROTL64(*rS, n);
1468 # long e = (me_5 << 4) | me_0_4;
1469 # unsigned_word m = MASK(0, e);
1470 # signed_word result = r & m;
1471 # *rA = result;
1472 # CR0_COMPARE(result, 0, Rc);
1473
1474 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
1475 # long n = MASKED(*rB, 59, 63);
1476 # unsigned32 r = ROTL32(*rS, n);
1477 # unsigned32 m = MASK(MB+32, ME+32);
1478 # signed_word result = r & m;
1479 # *rA = result;
1480 # CR0_COMPARE(result, 0, Rc);
1481 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
1482 # long n = (sh_5 << 4) | sh_0_4;
1483 # unsigned_word r = ROTL64(*rS, n);
1484 # long b = (mb_5 << 4) | mb_0_4;
1485 # unsigned_word m = MASK(b, (64-n));
1486 # signed_word result = (r & m) | (*rA & ~m)
1487 # *rA = result;
1488 # CR0_COMPARE(result, 0, Rc);
1489 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
1490 long n = SH;
1491 unsigned32 r = ROTL32(*rS, n);
1492 unsigned32 m = MASK(MB+32, ME+32);
1493 signed_word result = (r & m) | (*rA & ~m);
1494 *rA = result;
1495 ITRACE(trace_alu, (": n=%d *rS=0x%x r=0x%x m=0x%x result=0x%x\n",
1496 n, *rS, r, m, result));
1497 CR0_COMPARE(result, 0, Rc);
1498
1499
1500 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
1501 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
1502 int n = MASKED(*rB, 59, 63);
1503 unsigned32 source = *rS;
1504 signed_word shifted;
1505 if (n < 32)
1506 shifted = (source << n);
1507 else
1508 shifted = 0;
1509 *rA = shifted;
1510 CR0_COMPARE(shifted, 0, Rc);
1511 ITRACE(trace_alu,
1512 ("n=%d, source=0x%x, shifted=0x%x\n",
1513 n, source, shifted));
1514 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
1515 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
1516 int n = MASKED(*rB, 59, 63);
1517 unsigned32 source = *rS;
1518 signed_word shifted;
1519 if (n < 32)
1520 shifted = (source >> n);
1521 else
1522 shifted = 0;
1523 *rA = shifted;
1524 CR0_COMPARE(shifted, 0, Rc);
1525 ITRACE(trace_alu, \
1526 ("n=%d, source=0x%x, shifted=0x%x\n",
1527 n, source, shifted));
1528
1529 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
1530 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
1531 int n = SH;
1532 signed_word r = ROTL32(*rS, /*64*/32-n);
1533 signed_word m = MASK(n+32, 63);
1534 int S = MASKED(*rS, 32, 32);
1535 signed_word shifted = (r & m) | (S ? ~m : 0);
1536 *rA = shifted;
1537 if (S && ((r & ~m) & MASK(32, 63)) != 0)
1538 XER |= xer_carry;
1539 else
1540 XER &= ~xer_carry;
1541 CR0_COMPARE(shifted, 0, Rc);
1542 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
1543 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
1544 int n = MASKED(*rB, 58, 63);
1545 int shift = (n >= 31 ? 31 : n);
1546 signed32 source = (signed32)*rS; /* signed to keep sign bit */
1547 signed32 shifted = source >> shift;
1548 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
1549 *rA = (signed_word)shifted; /* if 64bit will sign extend */
1550 if (source < 0 && (source & mask))
1551 XER |= xer_carry;
1552 else
1553 XER &= ~xer_carry;
1554 CR0_COMPARE(shifted, 0, Rc);
1555
1556
1557 #
1558 # I.3.3.14 Move to/from System Register Instructions
1559 #
1560
1561 0.31,6.RS,11.spr,21.467,31./:XFX:::Move to Special Purpose Register
1562 int n = (spr{5:9} << 5) | spr{0:4};
1563 if (spr{0} && IS_PROBLEM_STATE(processor))
1564 program_interrupt(processor, cia,
1565 privileged_instruction_program_interrupt);
1566 else if (!spr_is_valid(n)
1567 || spr_is_readonly(n))
1568 program_interrupt(processor, cia,
1569 illegal_instruction_program_interrupt);
1570 else {
1571 spreg new_val = (spr_length(n) == 64
1572 ? *rS
1573 : MASKED(*rS, 32, 63));
1574 /* HACK - time base registers need to be updated immediatly */
1575 if (WITH_TIME_BASE) {
1576 signed64 time_base;
1577 switch (n) {
1578 case spr_tbu:
1579 cpu_set_time_base(processor,
1580 (MASKED64(cpu_get_time_base(processor),
1581 32, 63)
1582 | ((signed64)new_val << 32)));
1583 break;
1584 case spr_tbl:
1585 cpu_set_time_base(processor,
1586 (MASKED64(cpu_get_time_base(processor),
1587 32, 63)
1588 | ((signed64)new_val << 32)));
1589 break;
1590 case spr_dec:
1591 cpu_set_decrementer(processor, new_val);
1592 break;
1593 default:
1594 SPREG(n) = new_val;
1595 break;
1596 }
1597 }
1598 else {
1599 SPREG(n) = new_val;
1600 }
1601 }
1602 0.31,6.RT,11.spr,21.339,31./:XFX:uea::Move from Special Purpose Register
1603 int n = (spr{5:9} << 5) | spr{0:4};
1604 if (spr{0} && IS_PROBLEM_STATE(processor))
1605 program_interrupt(processor, cia,
1606 privileged_instruction_program_interrupt);
1607 else if (!spr_is_valid(n))
1608 program_interrupt(processor, cia,
1609 illegal_instruction_program_interrupt);
1610 else {
1611 /* HACK - some SPR's need to get their value extracted specially */
1612 *rT = SPREG(n);
1613 }
1614 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
1615 if (FXM == 0xff) {
1616 CR = *rS;
1617 }
1618 else {
1619 unsigned_word mask = 0;
1620 unsigned_word f;
1621 for (f = 0; f < 8; f++) {
1622 if (FXM & (0x80 >> f))
1623 mask |= (0xf << 4*(7-f));
1624 }
1625 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
1626 }
1627 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
1628 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
1629 *rT = (unsigned32)CR;
1630
1631 #
1632 # I.4.6.2 Floating-Point Load Instructions
1633 #
1634
1635 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
1636 unsigned_word b;
1637 unsigned_word EA;
1638 if (RA == 0) b = 0;
1639 else b = *rA;
1640 EA = b + EXTS(D);
1641 *frT = DOUBLE(MEM(unsigned, EA, 4));
1642 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
1643 unsigned_word b;
1644 unsigned_word EA;
1645 if (RA == 0) b = 0;
1646 else b = *rA;
1647 EA = b + *rB;
1648 *frT = DOUBLE(MEM(unsigned, EA, 4));
1649 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
1650 unsigned_word EA;
1651 if (RA == 0)
1652 program_interrupt(processor, cia,
1653 illegal_instruction_program_interrupt);
1654 EA = *rA + EXTS(D);
1655 *frT = DOUBLE(MEM(unsigned, EA, 4));
1656 *rA = EA;
1657 0.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
1658 unsigned_word EA;
1659 if (RA == 0)
1660 program_interrupt(processor, cia,
1661 illegal_instruction_program_interrupt);
1662 EA = *rA + *rB;
1663 *frT = DOUBLE(MEM(unsigned, EA, 4));
1664 *rA = EA;
1665
1666 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
1667 unsigned_word b;
1668 unsigned_word EA;
1669 if (RA == 0) b = 0;
1670 else b = *rA;
1671 EA = b + EXTS(D);
1672 *frT = MEM(unsigned, EA, 8);
1673 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
1674 unsigned_word b;
1675 unsigned_word EA;
1676 if (RA == 0) b = 0;
1677 else b = *rA;
1678 EA = b + *rB;
1679 *frT = MEM(unsigned, EA, 8);
1680 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
1681 unsigned_word EA;
1682 if (RA == 0)
1683 program_interrupt(processor, cia,
1684 illegal_instruction_program_interrupt);
1685 EA = *rA + EXTS(D);
1686 *frT = MEM(unsigned, EA, 8);
1687 *rA = EA;
1688 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
1689 unsigned_word EA;
1690 if (RA == 0)
1691 program_interrupt(processor, cia,
1692 illegal_instruction_program_interrupt);
1693 EA = *rA + *rB;
1694 *frT = MEM(unsigned, EA, 8);
1695 *rA = EA;
1696
1697
1698 #
1699 # I.4.6.3 Floating-Point Store Instructions
1700 #
1701
1702 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
1703 unsigned_word b;
1704 unsigned_word EA;
1705 if (RA == 0) b = 0;
1706 else b = *rA;
1707 EA = b + EXTS(D);
1708 STORE(EA, 4, SINGLE(*frS));
1709 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
1710 unsigned_word b;
1711 unsigned_word EA;
1712 if (RA == 0) b = 0;
1713 else b = *rA;
1714 EA = b + *rB;
1715 STORE(EA, 4, SINGLE(*frS));
1716 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
1717 unsigned_word EA;
1718 if (RA == 0)
1719 program_interrupt(processor, cia,
1720 illegal_instruction_program_interrupt);
1721 EA = *rA + EXTS(D);
1722 STORE(EA, 4, SINGLE(*frS));
1723 *rA = EA;
1724 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
1725 unsigned_word EA;
1726 if (RA == 0)
1727 program_interrupt(processor, cia,
1728 illegal_instruction_program_interrupt);
1729 EA = *rA + *rB;
1730 STORE(EA, 4, SINGLE(*frS));
1731 *rA = EA;
1732
1733 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
1734 unsigned_word b;
1735 unsigned_word EA;
1736 if (RA == 0) b = 0;
1737 else b = *rA;
1738 EA = b + EXTS(D);
1739 STORE(EA, 8, *frS);
1740 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
1741 unsigned_word b;
1742 unsigned_word EA;
1743 if (RA == 0) b = 0;
1744 else b = *rA;
1745 EA = b + *rB;
1746 STORE(EA, 8, *frS);
1747 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
1748 unsigned_word EA;
1749 if (RA == 0)
1750 program_interrupt(processor, cia,
1751 illegal_instruction_program_interrupt);
1752 EA = *rA + EXTS(D);
1753 STORE(EA, 8, *frS);
1754 *rA = EA;
1755 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
1756 unsigned_word EA;
1757 if (RA == 0)
1758 program_interrupt(processor, cia,
1759 illegal_instruction_program_interrupt);
1760 EA = *rA + *rB;
1761 STORE(EA, 8, *frS);
1762 *rA = EA;
1763
1764
1765 #
1766 # I.4.6.4 Floating-Point Move Instructions
1767 #
1768
1769 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
1770 *frT = *frB;
1771 CR1_UPDATE(Rc);
1772 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
1773 *frT = *frB ^ BIT64(0);
1774 CR1_UPDATE(Rc);
1775 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
1776 *frT = *frB & ~BIT64(0);
1777 CR1_UPDATE(Rc);
1778 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
1779 *frT = *frB | BIT64(0);
1780 CR1_UPDATE(Rc);
1781
1782
1783
1784 #
1785 # I.4.6.5 Floating-Point Arithmetic Instructions
1786 #
1787
1788 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
1789 FPSCR_BEGIN;
1790 if (is_invalid_operation(processor, cia,
1791 *frA, *frB,
1792 fpscr_vxsnan | fpscr_vxisi,
1793 0, /*single?*/
1794 0) /*negate?*/) {
1795 invalid_arithemetic_operation(processor, cia,
1796 frT, *frA, *frB, 0,
1797 0, /*instruction_is_frsp*/
1798 0, /*instruction_is_convert_to_64bit*/
1799 0, /*instruction_is_convert_to_32bit*/
1800 0); /*single-precision*/
1801 }
1802 else {
1803 /*HACK!*/
1804 double s = *(double*)frA + *(double*)frB;
1805 *(double*)frT = s;
1806 }
1807 FPSCR_END(Rc);
1808 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
1809 FPSCR_BEGIN;
1810 if (is_invalid_operation(processor, cia,
1811 *frA, *frB,
1812 fpscr_vxsnan | fpscr_vxisi,
1813 1, /*single?*/
1814 0) /*negate?*/) {
1815 invalid_arithemetic_operation(processor, cia,
1816 frT, *frA, *frB, 0,
1817 0, /*instruction_is_frsp*/
1818 0, /*instruction_is_convert_to_64bit*/
1819 0, /*instruction_is_convert_to_32bit*/
1820 1); /*single-precision*/
1821 }
1822 else {
1823 /*HACK!*/
1824 float s = *(double*)frA + *(double*)frB;
1825 *(double*)frT = s;
1826 }
1827 FPSCR_END(Rc);
1828
1829 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
1830 FPSCR_BEGIN;
1831 if (is_invalid_operation(processor, cia,
1832 *frA, *frB,
1833 fpscr_vxsnan | fpscr_vxisi,
1834 0, /*single?*/
1835 1) /*negate?*/) {
1836 invalid_arithemetic_operation(processor, cia,
1837 frT, *frA, *frB, 0,
1838 0, /*instruction_is_frsp*/
1839 0, /*instruction_is_convert_to_64bit*/
1840 0, /*instruction_is_convert_to_32bit*/
1841 0); /*single-precision*/
1842 }
1843 else {
1844 /*HACK!*/
1845 double s = *(double*)frA - *(double*)frB;
1846 *(double*)frT = s;
1847 }
1848 FPSCR_END(Rc);
1849 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
1850 FPSCR_BEGIN;
1851 if (is_invalid_operation(processor, cia,
1852 *frA, *frB,
1853 fpscr_vxsnan | fpscr_vxisi,
1854 1, /*single?*/
1855 1) /*negate?*/) {
1856 invalid_arithemetic_operation(processor, cia,
1857 frT, *frA, *frB, 0,
1858 0, /*instruction_is_frsp*/
1859 0, /*instruction_is_convert_to_64bit*/
1860 0, /*instruction_is_convert_to_32bit*/
1861 1); /*single-precision*/
1862 }
1863 else {
1864 /*HACK!*/
1865 float s = *(double*)frA - *(double*)frB;
1866 *(double*)frT = s;
1867 }
1868 FPSCR_END(Rc);
1869
1870 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
1871 FPSCR_BEGIN;
1872 if (is_invalid_operation(processor, cia,
1873 *frA, *frC,
1874 fpscr_vxsnan | fpscr_vximz,
1875 0, /*single?*/
1876 0) /*negate?*/) {
1877 invalid_arithemetic_operation(processor, cia,
1878 frT, *frA, 0, *frC,
1879 0, /*instruction_is_frsp*/
1880 0, /*instruction_is_convert_to_64bit*/
1881 0, /*instruction_is_convert_to_32bit*/
1882 0); /*single-precision*/
1883 }
1884 else {
1885 /*HACK!*/
1886 double s = *(double*)frA * *(double*)frC;
1887 *(double*)frT = s;
1888 }
1889 FPSCR_END(Rc);
1890 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
1891 FPSCR_BEGIN;
1892 if (is_invalid_operation(processor, cia,
1893 *frA, *frC,
1894 fpscr_vxsnan | fpscr_vximz,
1895 1, /*single?*/
1896 0) /*negate?*/) {
1897 invalid_arithemetic_operation(processor, cia,
1898 frT, *frA, 0, *frC,
1899 0, /*instruction_is_frsp*/
1900 0, /*instruction_is_convert_to_64bit*/
1901 0, /*instruction_is_convert_to_32bit*/
1902 1); /*single-precision*/
1903 }
1904 else {
1905 /*HACK!*/
1906 float s = *(double*)frA * *(double*)frC;
1907 *(double*)frT = s;
1908 }
1909 FPSCR_END(Rc);
1910
1911 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
1912 FPSCR_BEGIN;
1913 if (is_invalid_operation(processor, cia,
1914 *frA, *frB,
1915 fpscr_vxsnan | fpscr_vxzdz,
1916 0, /*single?*/
1917 0) /*negate?*/) {
1918 invalid_arithemetic_operation(processor, cia,
1919 frT, *frA, *frB, 0,
1920 0, /*instruction_is_frsp*/
1921 0, /*instruction_is_convert_to_64bit*/
1922 0, /*instruction_is_convert_to_32bit*/
1923 0); /*single-precision*/
1924 }
1925 else {
1926 /*HACK!*/
1927 double s = *(double*)frA / *(double*)frB;
1928 *(double*)frT = s;
1929 }
1930 FPSCR_END(Rc);
1931 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
1932 FPSCR_BEGIN;
1933 if (is_invalid_operation(processor, cia,
1934 *frA, *frB,
1935 fpscr_vxsnan | fpscr_vxzdz,
1936 1, /*single?*/
1937 0) /*negate?*/) {
1938 invalid_arithemetic_operation(processor, cia,
1939 frT, *frA, *frB, 0,
1940 0, /*instruction_is_frsp*/
1941 0, /*instruction_is_convert_to_64bit*/
1942 0, /*instruction_is_convert_to_32bit*/
1943 1); /*single-precision*/
1944 }
1945 else {
1946 /*HACK!*/
1947 float s = *(double*)frA / *(double*)frB;
1948 *(double*)frT = s;
1949 }
1950 FPSCR_END(Rc);
1951
1952 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
1953 FPSCR_BEGIN;
1954 double product; /*HACK! - incorrectly loosing precision ... */
1955 /* compute the multiply */
1956 if (is_invalid_operation(processor, cia,
1957 *frA, *frC,
1958 fpscr_vxsnan | fpscr_vximz,
1959 0, /*single?*/
1960 0) /*negate?*/) {
1961 invalid_arithemetic_operation(processor, cia,
1962 (unsigned64*)&product, *frA, 0, *frC,
1963 0, /*instruction_is_frsp*/
1964 0, /*instruction_is_convert_to_64bit*/
1965 0, /*instruction_is_convert_to_32bit*/
1966 0); /*single-precision*/
1967 }
1968 else {
1969 /*HACK!*/
1970 product = *(double*)frA * *(double*)frC;
1971 }
1972 /* compute the add */
1973 if (is_invalid_operation(processor, cia,
1974 product, *frB,
1975 fpscr_vxsnan | fpscr_vxisi,
1976 0, /*single?*/
1977 0) /*negate?*/) {
1978 invalid_arithemetic_operation(processor, cia,
1979 frT, product, *frB, 0,
1980 0, /*instruction_is_frsp*/
1981 0, /*instruction_is_convert_to_64bit*/
1982 0, /*instruction_is_convert_to_32bit*/
1983 0); /*single-precision*/
1984 }
1985 else {
1986 /*HACK!*/
1987 double s = product + *(double*)frB;
1988 *(double*)frT = s;
1989 }
1990 FPSCR_END(Rc);
1991 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
1992
1993 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
1994 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
1995
1996 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
1997 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
1998
1999 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
2000 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
2001
2002
2003 #
2004 # I.4.6.6 Floating-Point Rounding and Conversion Instructions
2005 #
2006
2007 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
2008 int sign;
2009 int exp;
2010 unsigned64 frac_grx;
2011 /* split off cases for what to do */
2012 if (EXTRACTED64(*frB, 1, 11) < 897
2013 && EXTRACTED64(*frB, 1, 63) > 0) {
2014 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
2015 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
2016 }
2017 if (EXTRACTED64(*frB, 1, 11) > 1150
2018 && EXTRACTED64(*frB, 1, 11) < 2047) {
2019 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
2020 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
2021 }
2022 if (EXTRACTED64(*frB, 1, 11) > 896
2023 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
2024 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
2025 if (EXTRACTED64(*frB, 1, 11) == 2047) {
2026 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
2027 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
2028 if (EXTRACTED64(*frB, 12, 12) == 0
2029 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
2030 }
2031 /* handle them */
2032 Disabled_Exponent_Underflow:
2033 sign = EXTRACTED64(*frB, 0, 0);
2034 if (EXTRACTED64(*frB, 1, 11) == 0) {
2035 exp = -1022;
2036 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2037 }
2038 if (EXTRACTED64(*frB, 1, 11) > 0) {
2039 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2040 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2041 }
2042 Denormalize_Operand:
2043 /* G|R|X == zero from above */
2044 while (exp < -126) {
2045 exp = exp - 1;
2046 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
2047 | MASKED64(frac_grx, 55, 55));
2048 }
2049 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
2050 Round_Single(processor, sign, &exp, &frac_grx);
2051 FPSCR_SET_XX(FPSCR & fpscr_fi);
2052 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
2053 *frT = INSERTED64(sign, 0, 0);
2054 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
2055 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
2056 }
2057 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
2058 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
2059 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2060 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2061 }
2062 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
2063 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
2064 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
2065 }
2066 /*Normalize_Operand:*/
2067 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
2068 exp = exp - 1;
2069 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
2070 }
2071 *frT = (INSERTED64(sign, 0, 0)
2072 | INSERTED64(exp + 1023, 1, 11)
2073 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2074 }
2075 goto Done;
2076 Enabled_Exponent_Underflow:
2077 FPSCR_SET_UX(1);
2078 sign = EXTRACTED64(*frB, 0, 0);
2079 if (EXTRACTED64(*frB, 1, 11) == 0) {
2080 exp = -1022;
2081 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2082 }
2083 if (EXTRACTED64(*frB, 1, 11) > 0) {
2084 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2085 frac_grx = (BIT64(0) |
2086 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
2087 }
2088 /*Normalize_Operand:*/
2089 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
2090 exp = exp - 1;
2091 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
2092 }
2093 Round_Single(processor, sign, &exp, &frac_grx);
2094 FPSCR_SET_XX(FPSCR & fpscr_fi);
2095 exp = exp + 192;
2096 *frT = (INSERTED64(sign, 0, 0)
2097 | INSERTED64(exp + 1023, 1, 11)
2098 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2099 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2100 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2101 goto Done;
2102 Disabled_Exponent_Overflow:
2103 FPSCR_SET_OX(1);
2104 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
2105 if (EXTRACTED64(*frB, 0, 0) == 0) {
2106 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
2107 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
2108 }
2109 if (EXTRACTED64(*frB, 0, 0) == 1) {
2110 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
2111 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
2112 }
2113 }
2114 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
2115 if (EXTRACTED64(*frB, 0, 0) == 0) {
2116 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
2117 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2118 }
2119 if (EXTRACTED64(*frB, 0, 0) == 1) {
2120 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
2121 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2122 }
2123 }
2124 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
2125 if (EXTRACTED64(*frB, 0, 0) == 0) {
2126 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
2127 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
2128 }
2129 if (EXTRACTED64(*frB, 0, 0) == 1) {
2130 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
2131 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2132 }
2133 }
2134 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
2135 if (EXTRACTED64(*frB, 0, 0) == 0) {
2136 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
2137 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2138 }
2139 if (EXTRACTED64(*frB, 0, 0) == 1) {
2140 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
2141 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
2142 }
2143 }
2144 /* FPSCR[FR] <- undefined */
2145 FPSCR_SET_FI(1);
2146 FPSCR_SET_XX(1);
2147 goto Done;
2148 Enabled_Exponent_Overflow:
2149 sign = EXTRACTED64(*frB, 0, 0);
2150 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2151 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2152 Round_Single(processor, sign, &exp, &frac_grx);
2153 FPSCR_SET_XX(FPSCR & fpscr_fi);
2154 Enabled_Overflow:
2155 FPSCR_SET_OX(1);
2156 exp = exp - 192;
2157 *frT = (INSERTED64(sign, 0, 0)
2158 | INSERTED64(exp + 1023, 1, 11)
2159 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2160 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2161 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2162 goto Done;
2163 Zero_Operand:
2164 *frT = *frB;
2165 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
2166 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
2167 FPSCR_SET_FR(0);
2168 FPSCR_SET_FI(0);
2169 goto Done;
2170 Infinity_Operand:
2171 *frT = *frB;
2172 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
2173 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
2174 FPSCR_SET_FR(0);
2175 FPSCR_SET_FI(0);
2176 goto Done;
2177 QNaN_Operand:
2178 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
2179 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
2180 FPSCR_SET_FR(0);
2181 FPSCR_SET_FI(0);
2182 goto Done;
2183 SNaN_Operand:
2184 FPSCR_OR_VX(fpscr_vxsnan);
2185 if ((FPSCR & fpscr_ve) == 0) {
2186 *frT = (MASKED64(*frB, 0, 11)
2187 | BIT64(12)
2188 | MASKED64(*frB, 13, 34));
2189 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
2190 }
2191 FPSCR_SET_FR(0);
2192 FPSCR_SET_FI(0);
2193 goto Done;
2194 Normal_Operand:
2195 sign = EXTRACTED64(*frB, 0, 0);
2196 exp = EXTRACTED64(*frB, 1, 11) - 1023;
2197 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
2198 Round_Single(processor, sign, &exp, &frac_grx);
2199 FPSCR_SET_XX(FPSCR & fpscr_fi);
2200 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
2201 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
2202 *frT = (INSERTED64(sign, 0, 0)
2203 | INSERTED64(exp + 1023, 1, 11)
2204 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
2205 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2206 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
2207 goto Done;
2208 Done:
2209 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
2210 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
2211 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
2212 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
2213 FPSCR_BEGIN;
2214 convert_to_integer(processor, cia,
2215 frT, *frB,
2216 fpscr_rn_round_towards_zero, 32);
2217 FPSCR_END(Rc);
2218 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
2219 int sign = EXTRACTED64(*frB, 0, 0);
2220 int exp = 63;
2221 unsigned64 frac = *frB;
2222 if (frac == 0) goto Zero_Operand;
2223 if (sign == 1) frac = ~frac + 1;
2224 while (EXTRACTED64(frac, 0, 0) == 0) {
2225 /*??? do the loop 0 times if (FRB) = max negative integer */
2226 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
2227 exp = exp - 1;
2228 }
2229 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
2230 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2231 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
2232 *frT = (INSERTED64(sign, 0, 0)
2233 | INSERTED64(exp + 1023, 1, 11)
2234 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
2235 goto Done;
2236 /**/
2237 Zero_Operand:
2238 FPSCR_SET_FR(0);
2239 FPSCR_SET_FI(0);
2240 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
2241 *frT = 0;
2242 goto Done;
2243 /**/
2244 Done:
2245
2246 #
2247 # I.4.6.7 Floating-Point Compare Instructions
2248 #
2249
2250 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
2251 FPSCR_BEGIN;
2252 unsigned c;
2253 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
2254 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
2255 else if (is_less_than(frA, frB))
2256 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
2257 else if (is_greater_than(frA, frB))
2258 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
2259 else
2260 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
2261 FPSCR_SET_FPCC(c);
2262 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
2263 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
2264 FPSCR_OR_VX(fpscr_vxsnan);
2265 FPSCR_END(0);
2266 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
2267 FPSCR_BEGIN;
2268 unsigned c;
2269 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
2270 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
2271 else if (is_less_than(frA, frB))
2272 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
2273 else if (is_greater_than(frA, frB))
2274 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
2275 else
2276 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
2277 FPSCR_SET_FPCC(c);
2278 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
2279 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
2280 FPSCR_OR_VX(fpscr_vxsnan);
2281 if ((FPSCR & fpscr_ve) == 0)
2282 FPSCR_OR_VX(fpscr_vxvc);
2283 }
2284 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
2285 FPSCR_OR_VX(fpscr_vxvc);
2286 }
2287 FPSCR_END(0);
2288
2289
2290 #
2291 # I.4.6.8 Floating-Point Status and Control Register Instructions
2292 #
2293
2294 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
2295 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
2296 0.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
2297 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
2298 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
2299 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
2300
2301
2302 #
2303 # I.A.1.1 Floating-Point Store Instruction
2304 #
2305 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
2306
2307 #
2308 # I.A.1.2 Floating-Point Arithmetic Instructions
2309 #
2310
2311 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
2312 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
2313
2314 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
2315 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
2316
2317 #
2318 # I.A.1.3 Floating-Point Select Instruction
2319 #
2320
2321 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
2322
2323
2324 #
2325 # II.3.2 Cache Management Instructions
2326 #
2327
2328 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
2329 ; /* nop for now */
2330
2331 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
2332 cpu_synchronize_context(processor);
2333
2334
2335 #
2336 # II.3.2.2 Data Cache Instructions
2337 #
2338
2339 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
2340 ; /* nop for now */
2341
2342 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
2343 ; /* nop for now */
2344
2345 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
2346 ; /* nop for now */
2347
2348 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
2349 ; /* nop for now */
2350
2351 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
2352 ; /* nop for now */
2353
2354 #
2355 # II.3.3 Envorce In-order Execution of I/O Instruction
2356 #
2357
2358 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
2359 /* Since this model has no instruction overlap
2360 this instruction need do nothing */
2361
2362 #
2363 # II.4.1 Time Base Instructions
2364 #
2365
2366 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
2367 int n = (tbr{5:9} << 5) | tbr{0:4};
2368 if (n == 268) {
2369 if (is_64bit_implementation) *rT = TB;
2370 else *rT = EXTRACTED64(TB, 32, 63);
2371 }
2372 else if (n == 269) {
2373 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
2374 else *rT = EXTRACTED64(TB, 0, 31);
2375 }
2376 else
2377 program_interrupt(processor, cia,
2378 illegal_instruction_program_interrupt);
2379
2380
2381 #
2382 # III.2.3.1 System Linkage Instructions
2383 #
2384
2385 #0.17,6./,11./,16./,30.1,31./:SC:::System Call
2386 0.19,6./,11./,16./,21.50,31./:XL:::Return From Interrupt
2387
2388 #
2389 # III.3.4.1 Move to/from System Register Instructions
2390 #
2391
2392 #0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
2393 #0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
2394 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
2395 if (IS_PROBLEM_STATE(processor))
2396 program_interrupt(processor, cia,
2397 privileged_instruction_program_interrupt);
2398 else
2399 MSR = *rS;
2400 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
2401 if (IS_PROBLEM_STATE(processor))
2402 program_interrupt(processor, cia,
2403 privileged_instruction_program_interrupt);
2404 else
2405 *rT = MSR;
2406
2407
2408 #
2409 # III.4.11.1 Cache Management Instructions
2410 #
2411
2412 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
2413 ; /* nop for now */
2414
2415 #
2416 # III.4.11.2 Segment Register Manipulation Instructions
2417 #
2418
2419 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
2420 if (IS_PROBLEM_STATE(processor))
2421 program_interrupt(processor, cia,
2422 privileged_instruction_program_interrupt);
2423 else
2424 SEGREG(SR) = *rS;
2425 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
2426 if (IS_PROBLEM_STATE(processor))
2427 program_interrupt(processor, cia,
2428 privileged_instruction_program_interrupt);
2429 else
2430 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
2431 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
2432 if (IS_PROBLEM_STATE(processor))
2433 program_interrupt(processor, cia,
2434 privileged_instruction_program_interrupt);
2435 else
2436 *rT = SEGREG(SR);
2437 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
2438 if (IS_PROBLEM_STATE(processor))
2439 program_interrupt(processor, cia,
2440 privileged_instruction_program_interrupt);
2441 else
2442 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
2443
2444
2445 #
2446 # III.4.11.3 Lookaside Buffer Management Instructions (Optional)
2447 #
2448
2449 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
2450 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
2451
2452 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
2453 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
2454
2455 0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
2456
2457
2458 #
2459 # III.A.1.2 External Access Instructions
2460 #
2461
2462 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
2463 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
This page took 0.080763 seconds and 5 git commands to generate.