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