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