merge from gcc
[deliverable/binutils-gdb.git] / sim / ppc / ppc-instructions
CommitLineData
c906108c
SS
1#
2# This file is part of the program psim.
3#
d81bb16a 4# Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney
c906108c
SS
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#
d81bb16a
AC
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)
c906108c
SS
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
294void::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
325void::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
350void::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
382void::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
441model_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
470model_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.
493void::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
505void::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
520void::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
546void::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
578void::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
605void::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
630void::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
657void::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
685void::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
704void::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
722void::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
742void::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
778model_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
794void::model-function::model_init:model_data *model_ptr
795
796void::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
801unsigned_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
807unsigned_word::model-function::model_get_number_of_cycles:model_data *model_ptr
808 return (model_ptr->nr_cycles);
809
810model_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
940void::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
947void::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
957void::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
983unsigned64::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
1025unsigned32::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
1056void::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#
1093void::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
1117void::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
1150void::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
1271int::function::sign:unsigned64 FRS
1272 return (MASKED64(FRS, 0, 0)
1273 ? -1
1274 : 1);
1275int::function::biased_exp:unsigned64 frs, int single
1276 if (single)
1277 return EXTRACTED64(frs, 1, 8);
1278 else
1279 return EXTRACTED64(frs, 1, 11);
1280unsigned64::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.
1288int::function::is_nor:unsigned64 frs, int single
1289 int exp = biased_exp(frs, single);
1290 return (exp >= 1
1291 && exp <= (single ? 254 : 2046));
1292int::function::is_zero:unsigned64 FRS
1293 return (MASKED64(FRS, 1, 63) == 0
1294 ? sign(FRS)
1295 : 0);
1296int::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);
1302int::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);
1308int::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);
1314int::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);
1319int::function::is_QNaN:unsigned64 frs, int single
1320 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1321int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1322 return *(double*)fra < *(double*)frb;
1323int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1324 return *(double*)fra > *(double*)frb;
1325int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1326 return *(double*)fra == *(double*)frb;
1327
1328
1329# which quiet nan should become the result
1330unsigned64::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
1349int::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
1406void::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
1435int::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
1447void::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#
14770.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#
14850.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
7a292a7a 1490 /* option_mpc860c0:
c906108c
SS
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
14980.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);
7a292a7a
SS
1519 if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
1520 /* This branch is predicted as "normal".
c906108c
SS
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 }
c906108c
SS
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
15410.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);
7a292a7a 1561 if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
c906108c
SS
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 }
c906108c
SS
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
15760.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);
7a292a7a 1592 if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) {
c906108c
SS
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 }
c906108c
SS
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#
16100.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#
16220.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
16300.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
16380.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
16460.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
16540.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
16620.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
16700.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
16780.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#
16890.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
17020.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
17160.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
17290.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
17430.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
17570.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
17700.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
17830.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
17970.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
18110.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
18240.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
18370.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
18510.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
18650.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
18780.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
18910.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
19050.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
19190.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
19270.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
19350.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
19440.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
19520.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
19600.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
19690.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
19840.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
19970.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
20100.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
20240.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
20380.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
20510.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
20640.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
20780.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
20920.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
21050.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
21180.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
21320.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
21460.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);
21530.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);
21600.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;
21680.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
21820.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
21950.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
22080.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
22210.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
22390.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
22580.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
22800.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);
21f86aab 2306 i = i + 8;
c906108c
SS
2307 if (i == 64) i = 32;
2308 EA = EA + 1;
2309 n = n - 1;
2310 }
2311
23120.31,6.RT,11.RA,16.RB,21.533,31./:X:::Load String Word Indexed
2313 unsigned_word EA;
2314 unsigned_word b;
2315 int n;
2316 int r;
2317 int i;
2318 int nr;
2319 if (RA_is_0) b = 0;
2320 else b = *rA;
2321 EA = b + *rB;
2322 n = EXTRACTED32(XER, 25, 31);
2323 r = RT - 1;
2324 i = 32;
2325 nr = (n + 3) / 4;
ec80ed80
AC
2326 if (((RT + nr >= 32)
2327 ? ((RA >= RT || RA < (RT + nr) % 32)
2328 || (RB >= RT || RB < (RT + nr) % 32))
2329 : ((RA >= RT && RA < RT + nr)
2330 || (RB >= RT && RB < RT + nr)))
c906108c
SS
2331 || (RT == RA || RT == RB))
2332 program_interrupt(processor, cia,
2333 illegal_instruction_program_interrupt);
2334 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2335 alignment_interrupt(processor, cia, EA);
2336 while (n > 0) {
2337 if (i == 32) {
2338 r = (r + 1) % 32;
ec80ed80 2339 GPR(r) = 0;
c906108c
SS
2340 }
2341 GPR(r) |= INSERTED(MEM(unsigned, EA, 1), i, i+7);
2342 i = i + 8;
2343 if (i == 64) i = 32;
2344 EA = EA + 1;
2345 n = n - 1;
2346 }
2347
23480.31,6.RS,11.RA,16.NB,21.725,31./:X:::Store String Word Immedate
2349 unsigned_word EA;
2350 int n;
2351 int r;
2352 int i;
2353 if (RA_is_0) EA = 0;
2354 else EA = *rA;
2355 if (NB == 0) n = 32;
2356 else n = NB;
2357 r = RS - 1;
2358 i = 32;
2359 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2360 alignment_interrupt(processor, cia, EA);
2361 while (n > 0) {
2362 if (i == 32) r = (r + 1) % 32;
2363 STORE(EA, 1, EXTRACTED(GPR(r), i, i+7));
2364 i = i + 8;
2365 if (i == 64) i = 32;
2366 EA = EA + 1;
2367 n = n - 1;
2368 }
2369
23700.31,6.RS,11.RA,16.RB,21.661,31./:X:::Store String Word Indexed
2371 unsigned_word EA;
2372 unsigned_word b;
2373 int n;
2374 int r;
2375 int i;
2376 if (RA_is_0) b = 0;
2377 else b = *rA;
2378 EA = b + *rB;
2379 if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT)
2380 alignment_interrupt(processor, cia, EA);
2381 n = EXTRACTED32(XER, 25, 31);
2382 r = RS - 1;
2383 i = 32;
2384 while (n > 0) {
2385 if (i == 32) r = (r + 1) % 32;
2386 STORE(EA, 1, EXTRACTED(GPR(r), i, i+7));
2387 i = i + 8;
2388 if (i == 64) i = 32;
2389 EA = EA + 1;
2390 n = n - 1;
2391 }
2392
2393
2394#
2395# I.3.3.7 Storage Synchronization Instructions
2396#
2397# HACK: Rather than monitor addresses looking for a reason
2398# to cancel a reservation. This code instead keeps
2399# a copy of the data read from memory. Before performing
2400# a store, the memory area is checked to see if it has
2401# been changed.
24020.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
2403*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2404*603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2405*603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2406*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
2407 unsigned_word b;
2408 unsigned_word EA;
2409 if (RA_is_0) b = 0;
2410 else b = *rA;
2411 EA = b + *rB;
2412 RESERVE = 1;
2413 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2414 RESERVE_DATA = MEM(unsigned, EA, 4);
2415 *rT = RESERVE_DATA;
2416 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2417
24180.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2419 unsigned_word b;
2420 unsigned_word EA;
2421 if (RA_is_0) b = 0;
2422 else b = *rA;
2423 EA = b + *rB;
2424 RESERVE = 1;
2425 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2426 RESERVE_DATA = MEM(unsigned, EA, 8);
2427 *rT = RESERVE_DATA;
2428 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
2429
24300.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
2431*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2432*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2433*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2434*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
2435 unsigned_word b;
2436 unsigned_word EA;
2437 if (RA_is_0) b = 0;
2438 else b = *rA;
2439 EA = b + *rB;
2440 if (RESERVE) {
2441 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2442 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2443 STORE(EA, 4, *rS);
2444 CR_SET_XER_SO(0, cr_i_zero);
2445 }
2446 else {
2447 /* ment to randomly to store, we never do! */
2448 CR_SET_XER_SO(0, 0);
2449 }
2450 RESERVE = 0;
2451 }
2452 else {
2453 CR_SET_XER_SO(0, 0);
2454 }
2455 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2456
24570.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2458 unsigned_word b;
2459 unsigned_word EA;
2460 if (RA_is_0) b = 0;
2461 else b = *rA;
2462 EA = b + *rB;
2463 if (RESERVE) {
2464 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2465 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2466 STORE(EA, 8, *rS);
2467 CR_SET_XER_SO(0, cr_i_zero);
2468 }
2469 else {
2470 /* ment to randomly to store, we never do */
2471 CR_SET_XER_SO(0, 0);
2472 }
2473 RESERVE = 0;
2474 }
2475 else {
2476 CR_SET_XER_SO(0, 0);
2477 }
2478 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2479
24800.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
2481*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2482*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2483*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2484*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
2485 /* do nothing */
2486
2487
2488#
2489# I.3.3.9 Fixed-Point Arithmetic Instructions
2490#
2491
24920.14,6.RT,11.RA,16.SI:D:::Add Immediate
2493*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2494*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2495*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2496*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2497 if (RA_is_0) *rT = EXTS(SI);
2498 else *rT = *rA + EXTS(SI);
2499 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2500 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2501
25020.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
2503*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2504*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2505*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2506*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2507 if (RA_is_0) *rT = EXTS(SI) << 16;
2508 else *rT = *rA + (EXTS(SI) << 16);
2509 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
2510 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
2511
25120.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
2513*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2514*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2515*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2516*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2517 ALU_BEGIN(*rA);
2518 ALU_ADD(*rB);
2519 ALU_END(*rT, 0/*CA*/, OE, Rc);
2520 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2521
25220.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
2523*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2524*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2525*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2526*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2527 ALU_BEGIN(*rA);
2528 ALU_NOT;
2529 ALU_ADD(*rB);
2530 ALU_ADD(1);
2531 ALU_END(*rT, 0/*CA*/, OE, Rc);
2532 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2533
25340.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
2535*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2536*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2537*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2538*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2539 ALU_BEGIN(*rA);
2540 ALU_ADD(EXTS(SI));
2541 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2542 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2543
25440.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
2545*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2546*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2547*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2548*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2549 ALU_BEGIN(*rA);
2550 ALU_ADD(EXTS(SI));
2551 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
2552 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
2553
25540.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
2555*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2556*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2557*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2558*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2559 ALU_BEGIN(*rA);
2560 ALU_NOT;
2561 ALU_ADD(EXTS(SI));
2562 ALU_ADD(1);
2563 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
2564 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2565
25660.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
2567*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2568*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2569*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2570*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2571 ALU_BEGIN(*rA);
2572 ALU_ADD(*rB);
2573 ALU_END(*rT, 1/*CA*/, OE, Rc);
2574 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2575
25760.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
2577*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2578*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2579*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2580*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2581 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2582 ALU_BEGIN(*rA);
2583 ALU_NOT;
2584 ALU_ADD(*rB);
2585 ALU_ADD(1);
2586 ALU_END(*rT, 1/*CA*/, OE, Rc);
2587 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2588
25890.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
2590*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2591*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2592*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2593*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2594 ALU_BEGIN(*rA);
2595 ALU_ADD(*rB);
2596 ALU_ADD_CA;
2597 ALU_END(*rT, 1/*CA*/, OE, Rc);
2598 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2599
26000.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
2601*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2602*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2603*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2604*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2605 ALU_BEGIN(*rA);
2606 ALU_NOT;
2607 ALU_ADD(*rB);
2608 ALU_ADD_CA;
2609 ALU_END(*rT, 1/*CA*/, OE, Rc);
2610 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2611
26120.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
2613*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2614*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2615*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2616*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2617 ALU_BEGIN(*rA);
2618 ALU_ADD_CA;
2619 ALU_ADD(-1);
2620 ALU_END(*rT, 1/*CA*/, OE, Rc);
2621 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2622
26230.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
2624*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2625*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2626*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2627*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2628 ALU_BEGIN(*rA);
2629 ALU_NOT;
2630 ALU_ADD_CA;
2631 ALU_ADD(-1);
2632 ALU_END(*rT, 1/*CA*/, OE, Rc);
2633 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2634
26350.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
2636*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2637*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2638*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2639*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2640 ALU_BEGIN(*rA);
2641 ALU_ADD_CA;
2642 ALU_END(*rT, 1/*CA*/, OE, Rc);
2643 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2644
26450.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
2646*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2647*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2648*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2649*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2650 ALU_BEGIN(*rA);
2651 ALU_NOT;
2652 ALU_ADD_CA;
2653 ALU_END(*rT, 1/*CA*/, OE, Rc);
2654 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2655
26560.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
2657*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2658*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2659*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2660*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2661 ALU_BEGIN(*rA);
2662 ALU_NOT;
2663 ALU_ADD(1);
2664 ALU_END(*rT,0/*CA*/,OE,Rc);
2665 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
2666
26670.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
2668*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2669*603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2670*603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2671*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
2672 signed_word prod = *rA * EXTS(SI);
2673 *rT = prod;
2674 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
2675
26760.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
2677
26780.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
2679*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2680*603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2681*603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2682*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2683 signed64 a = (signed32)(*rA);
2684 signed64 b = (signed32)(*rB);
2685 signed64 prod = a * b;
2686 signed_word t = prod;
2687 *rT = *rA * *rB;
2688 if (t != prod && OE)
2689 XER |= (xer_overflow | xer_summary_overflow);
2690 CR0_COMPARE(t, 0, Rc);
2691 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2692
26930.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
2694
26950.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
2696*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2697*603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2698*603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2699*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2700 signed64 a = (signed32)(*rA);
2701 signed64 b = (signed32)(*rB);
2702 signed64 prod = a * b;
2703 signed_word t = EXTRACTED64(prod, 0, 31);
2704 *rT = t;
2705 CR0_COMPARE(t, 0, Rc);
2706 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2707
27080.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
2709
27100.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::mulhwu:Multiply High Word Unsigned
2711*601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2712*603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2713*603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2714*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
2715 unsigned64 a = (unsigned32)(*rA);
2716 unsigned64 b = (unsigned32)(*rB);
2717 unsigned64 prod = a * b;
2718 signed_word t = EXTRACTED64(prod, 0, 31);
2719 *rT = t;
2720 CR0_COMPARE(t, 0, Rc);
2721 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2722
27230.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
2724
27250.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
2726*601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2727*603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2728*603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2729*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2730 signed64 dividend = (signed32)(*rA);
2731 signed64 divisor = (signed32)(*rB);
2732 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2733 || (dividend == 0x80000000 && divisor == -1)) {
2734 if (OE)
2735 XER |= (xer_overflow | xer_summary_overflow);
2736 CR0_COMPARE(0, 0, Rc);
2737 }
2738 else {
2739 signed64 quotent = dividend / divisor;
2740 *rT = quotent;
2741 CR0_COMPARE((signed_word)quotent, 0, Rc);
2742 }
2743 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2744
27450.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
2746
27470.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
2748*601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2749*603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2750*603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2751*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
2752 unsigned64 dividend = (unsigned32)(*rA);
2753 unsigned64 divisor = (unsigned32)(*rB);
2754 if (divisor == 0) {
2755 if (OE)
2756 XER |= (xer_overflow | xer_summary_overflow);
2757 CR0_COMPARE(0, 0, Rc);
2758 }
2759 else {
2760 unsigned64 quotent = dividend / divisor;
2761 *rT = quotent;
2762 CR0_COMPARE((signed_word)quotent, 0, Rc);
2763 }
2764 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
2765
2766
2767#
2768# I.3.3.10 Fixed-Point Compare Instructions
2769#
2770
27710.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
2772*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2773*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2774*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2775*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2776 if (!is_64bit_mode && L)
2777 program_interrupt(processor, cia,
2778 illegal_instruction_program_interrupt);
2779 else {
2780 signed_word a;
2781 signed_word b = EXTS(SI);
2782 if (L == 0)
2783 a = EXTENDED(*rA);
2784 else
2785 a = *rA;
2786 CR_COMPARE(BF, a, b);
2787 }
2788 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2789
27900.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
2791*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2792*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2793*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2794*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2795 if (!is_64bit_mode && L)
2796 program_interrupt(processor, cia,
2797 illegal_instruction_program_interrupt);
2798 else {
2799 signed_word a;
2800 signed_word b;
2801 if (L == 0) {
2802 a = EXTENDED(*rA);
2803 b = EXTENDED(*rB);
2804 }
2805 else {
2806 a = *rA;
2807 b = *rB;
2808 }
2809 CR_COMPARE(BF, a, b);
2810 }
2811 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2812
28130.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
2814*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2815*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2816*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2817*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2818 if (!is_64bit_mode && L)
2819 program_interrupt(processor, cia,
2820 illegal_instruction_program_interrupt);
2821 else {
2822 unsigned_word a;
2823 unsigned_word b = UI;
2824 if (L == 0)
2825 a = MASKED(*rA, 32, 63);
2826 else
2827 a = *rA;
2828 CR_COMPARE(BF, a, b);
2829 }
2830 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
2831
28320.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
2833*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2834*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2835*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2836*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2837 if (!is_64bit_mode && L)
2838 program_interrupt(processor, cia,
2839 illegal_instruction_program_interrupt);
2840 else {
2841 unsigned_word a;
2842 unsigned_word b;
2843 if (L == 0) {
2844 a = MASKED(*rA, 32, 63);
2845 b = MASKED(*rB, 32, 63);
2846 }
2847 else {
2848 a = *rA;
2849 b = *rB;
2850 }
2851 CR_COMPARE(BF, a, b);
2852 }
2853 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
2854
2855
2856#
2857# I.3.3.11 Fixed-Point Trap Instructions
2858#
2859
28600.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2861 if (!is_64bit_mode)
2862 program_interrupt(processor, cia,
2863 illegal_instruction_program_interrupt);
2864 else {
2865 signed_word a = *rA;
2866 signed_word b = EXTS(SI);
2867 if ((a < b && TO{0})
2868 || (a > b && TO{1})
2869 || (a == b && TO{2})
2870 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2871 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2872 )
2873 program_interrupt(processor, cia,
2874 trap_program_interrupt);
2875 }
2876
28770.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
2878*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2879*603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2880*603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2881*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2882 signed_word a = EXTENDED(*rA);
2883 signed_word b = EXTS(SI);
2884 if ((a < b && TO{0})
2885 || (a > b && TO{1})
2886 || (a == b && TO{2})
2887 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2888 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2889 )
2890 program_interrupt(processor, cia,
2891 trap_program_interrupt);
2892
28930.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2894 if (!is_64bit_mode)
2895 program_interrupt(processor, cia,
2896 illegal_instruction_program_interrupt);
2897 else {
2898 signed_word a = *rA;
2899 signed_word b = *rB;
2900 if ((a < b && TO{0})
2901 || (a > b && TO{1})
2902 || (a == b && TO{2})
2903 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2904 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2905 )
2906 program_interrupt(processor, cia,
2907 trap_program_interrupt);
2908 }
2909
29100.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
2911*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2912*603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2913*603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2914*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2915 signed_word a = EXTENDED(*rA);
2916 signed_word b = EXTENDED(*rB);
2917 if (TO == 12 && rA == rB) {
2918 ITRACE(trace_breakpoint, ("breakpoint\n"));
2919 cpu_halt(processor, cia, was_trap, 0);
2920 }
2921 else if ((a < b && TO{0})
2922 || (a > b && TO{1})
2923 || (a == b && TO{2})
2924 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2925 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2926 )
2927 program_interrupt(processor, cia,
2928 trap_program_interrupt);
2929
2930#
2931# I.3.3.12 Fixed-Point Logical Instructions
2932#
2933
29340.28,6.RS,11.RA,16.UI:D:::AND Immediate
2935*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2936*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2937*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2938*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2939 *rA = *rS & UI;
2940 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2941 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2942 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2943
29440.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
2945*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2946*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2947*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2948*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2949 *rA = *rS & (UI << 16);
2950 CR0_COMPARE(*rA, 0, 1/*Rc*/);
2951 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2952 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
2953
29540.24,6.RS,11.RA,16.UI:D:::OR Immediate
2955*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2956*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2957*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2958*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2959 *rA = *rS | UI;
2960 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2961 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2962
29630.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
2964*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2965*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2966*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2967*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2968 *rA = *rS | (UI << 16);
2969 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2970 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2971
29720.26,6.RS,11.RA,16.UI:D:::XOR Immediate
2973*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2974*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2975*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2976*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2977 *rA = *rS ^ UI;
2978 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2979 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2980
29810.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
2982*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2983*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2984*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2985*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2986 *rA = *rS ^ (UI << 16);
2987 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2988 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
2989
29900.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
2991*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2992*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2993*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2994*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
2995 *rA = *rS & *rB;
2996 CR0_COMPARE(*rA, 0, Rc);
2997 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2998 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
2999
30000.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
3001*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3002*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3003*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3004*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3005 *rA = *rS | *rB;
3006 CR0_COMPARE(*rA, 0, Rc);
3007 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3008 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3009
30100.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
3011*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3012*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3013*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3014*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3015 *rA = *rS ^ *rB;
3016 CR0_COMPARE(*rA, 0, Rc);
3017 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3018 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3019
30200.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
3021*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3022*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3023*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3024*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3025 *rA = ~(*rS & *rB);
3026 CR0_COMPARE(*rA, 0, Rc);
3027 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3028 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3029
30300.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
3031*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3032*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3033*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3034*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3035 *rA = ~(*rS | *rB);
3036 CR0_COMPARE(*rA, 0, Rc);
3037 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3038 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3039
30400.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
3041*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3042*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3043*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3044*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3045 *rA = ~(*rS ^ *rB); /* A === B */
3046 CR0_COMPARE(*rA, 0, Rc);
3047 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3048 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3049
30500.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
3051*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3052*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3053*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3054*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3055 *rA = *rS & ~*rB;
3056 CR0_COMPARE(*rA, 0, Rc);
3057 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3058 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3059
30600.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
3061*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3062*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3063*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3064*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3065 *rA = *rS | ~*rB;
3066 CR0_COMPARE(*rA, 0, Rc);
3067 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3068 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
3069
30700.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
3071*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3072*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3073*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3074*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3075 *rA = (signed_word)(signed8)*rS;
3076 CR0_COMPARE(*rA, 0, Rc);
3077 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3078 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3079
30800.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
3081*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3082*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3083*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3084*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3085 *rA = (signed_word)(signed16)*rS;
3086 CR0_COMPARE(*rA, 0, Rc);
3087 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3088 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3089
30900.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
3091*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3092*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3093*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3094*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3095# *rA = (signed_word)(signed32)*rS;
3096# CR0_COMPARE(*rA, 0, Rc);
3097
30980.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
3099# int count = 0;
3100# unsigned64 mask = BIT64(0);
3101# unsigned64 source = *rS;
3102# while (!(source & mask) && mask != 0) {
3103# mask >>= 1;
3104# count++;
3105# }
3106# *rA = count;
3107# CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3108
31090.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
3110*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3111*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3112*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3113*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3114 int count = 0;
3115 unsigned32 mask = BIT32(0);
3116 unsigned32 source = *rS;
3117 while (!(source & mask) && mask != 0) {
3118 mask >>= 1;
3119 count++;
3120 }
3121 *rA = count;
3122 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3123 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
3124
3125
3126#
3127# I.3.3.13 Fixed-Point Rotate and Shift Instructions
3128#
3129
31300.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
3131# long n = (sh_5 << 4) | sh_0_4;
3132# unsigned_word r = ROTL64(*rS, n);
3133# long b = (mb_5 << 4) | mb_0_4;
3134# unsigned_word m = MASK(b, 63);
3135# signed_word result = r & m;
3136# *rA = result;
3137# ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
3138# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3139
31400.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
3141# long n = (sh_5 << 4) | sh_0_4;
3142# unsigned_word r = ROTL64(*rS, n);
3143# long e = (me_5 << 4) | me_0_4;
3144# unsigned_word m = MASK(0, e);
3145# signed_word result = r & m;
3146# *rA = result;
3147# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3148
31490.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
3150# long n = (sh_5 << 4) | sh_0_4;
3151# unsigned_word r = ROTL64(*rS, n);
3152# long b = (mb_5 << 4) | mb_0_4;
3153# unsigned_word m = MASK(0, (64-n));
3154# signed_word result = r & m;
3155# *rA = result;
3156# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
3157
31580.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
3159*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3160*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3161*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3162*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3163 long n = SH;
3164 unsigned32 s = *rS;
3165 unsigned32 r = ROTL32(s, n);
3166 unsigned32 m = MASK(MB+32, ME+32);
3167 signed_word result = r & m;
3168 *rA = result;
3169 CR0_COMPARE(result, 0, Rc);
3170 ITRACE(trace_alu,
3171 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
3172 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
3173 (unsigned long)result, (unsigned long)CR));
3174 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3175
31760.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
3177# long n = MASKED(*rB, 58, 63);
3178# unsigned_word r = ROTL64(*rS, n);
3179# long b = (mb_5 << 4) | mb_0_4;
3180# unsigned_word m = MASK(b, 63);
3181# signed_word result = r & m;
3182# *rA = result;
3183# CR0_COMPARE(result, 0, Rc);
3184
31850.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
3186# long n = MASKED(*rB, 58, 63);
3187# unsigned_word r = ROTL64(*rS, n);
3188# long e = (me_5 << 4) | me_0_4;
3189# unsigned_word m = MASK(0, e);
3190# signed_word result = r & m;
3191# *rA = result;
3192# CR0_COMPARE(result, 0, Rc);
3193
31940.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
3195 long n = MASKED(*rB, 59, 63);
3196 unsigned32 r = ROTL32(*rS, n);
3197 unsigned32 m = MASK(MB+32, ME+32);
3198 signed_word result = r & m;
3199 *rA = result;
3200 CR0_COMPARE(result, 0, Rc);
3201
32020.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
3203# long n = (sh_5 << 4) | sh_0_4;
3204# unsigned_word r = ROTL64(*rS, n);
3205# long b = (mb_5 << 4) | mb_0_4;
3206# unsigned_word m = MASK(b, (64-n));
3207# signed_word result = (r & m) | (*rA & ~m)
3208# *rA = result;
3209# CR0_COMPARE(result, 0, Rc);
3210
32110.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
3212*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3213*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3214*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3215*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3216 long n = SH;
3217 unsigned32 r = ROTL32(*rS, n);
3218 unsigned32 m = MASK(MB+32, ME+32);
3219 signed_word result = (r & m) | (*rA & ~m);
3220 *rA = result;
3221 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
3222 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
3223 (unsigned long)result));
3224 CR0_COMPARE(result, 0, Rc);
3225 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3226
3227
32280.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
3229
32300.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
3231*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3232*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3233*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3234*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3235 int n = MASKED(*rB, 58, 63);
3236 unsigned32 source = *rS;
3237 signed_word shifted;
3238 if (n < 32)
3239 shifted = (source << n);
3240 else
3241 shifted = 0;
3242 *rA = shifted;
3243 CR0_COMPARE(shifted, 0, Rc);
3244 ITRACE(trace_alu,
3245 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3246 n, (unsigned long)source, (unsigned long)shifted));
3247 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3248
32490.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
3250
32510.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
3252*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3253*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3254*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3255*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3256 int n = MASKED(*rB, 58, 63);
3257 unsigned32 source = *rS;
3258 signed_word shifted;
3259 if (n < 32)
3260 shifted = (source >> n);
3261 else
3262 shifted = 0;
3263 *rA = shifted;
3264 CR0_COMPARE(shifted, 0, Rc);
3265 ITRACE(trace_alu, \
3266 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3267 n, (unsigned long)source, (unsigned long)shifted));
3268 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3269
32700.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
3271
32720.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
3273*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3274*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3275*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3276*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3277 int n = SH;
3278 signed_word r = ROTL32(*rS, /*64*/32-n);
3279 signed_word m = MASK(n+32, 63);
3280 int S = MASKED(*rS, 32, 32);
3281 signed_word shifted = (r & m) | (S ? ~m : 0);
3282 *rA = shifted;
3283 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3284 XER |= xer_carry;
3285 else
3286 XER &= ~xer_carry;
3287 CR0_COMPARE(shifted, 0, Rc);
3288 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3289 (long)*rA, (long)*rA, (long)XER));
3290 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3291
32920.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
3293
32940.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
3295*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3296*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3297*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3298*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3299 unsigned64 mask;
3300 int n = MASKED(*rB, 59, 63);
3301 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3302 signed32 shifted = source >> n;
3303 int S = (MASKED(*rS,32,32) != 0);
3304 signed64 r = ((unsigned64) source);
3305 r = ((unsigned64) source) << 32 | (unsigned32) source;
3306 r = ROTL64(r,64-n);
3307 if (MASKED(*rB,58,58) == 0)
3308 mask = (unsigned64) MASK64(n+32,63);
3309 else
3310 mask = (unsigned64) 0;
3311 *rA = (signed_word) (r & mask | ((signed64) -1*S) & ~mask); /* if 64bit will sign extend */
3312 if (S && (MASKED(r & ~mask,32,63)!=0))
3313 XER |= xer_carry;
3314 else
3315 XER &= ~xer_carry;
3316 CR0_COMPARE(*rA, 0, Rc);
3317 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3318 (long)*rA, (long)*rA, (long)XER));
3319 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
3320
3321#
3322# I.3.3.14 Move to/from System Register Instructions
3323#
3324
33250.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
3326*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3327*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3328*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3329*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3330 int n = (SPR{5:9} << 5) | SPR{0:4};
3331 if (SPR{0} && IS_PROBLEM_STATE(processor))
3332 program_interrupt(processor, cia,
3333 privileged_instruction_program_interrupt);
3334 else if (!spr_is_valid(n)
3335 || spr_is_readonly(n))
3336 program_interrupt(processor, cia,
3337 illegal_instruction_program_interrupt);
3338 else {
3339 spreg new_val = (spr_length(n) == 64
3340 ? *rS
3341 : MASKED(*rS, 32, 63));
3342 /* HACK - time base registers need to be updated immediatly */
3343 if (WITH_TIME_BASE) {
3344 switch (n) {
3345 case spr_tbu:
3346 cpu_set_time_base(processor,
3347 (MASKED64(cpu_get_time_base(processor), 32, 63)
3348 | INSERTED64(new_val, 0, 31)));
3349 break;
3350 case spr_tbl:
3351 cpu_set_time_base(processor,
3352 (MASKED64(cpu_get_time_base(processor), 0, 31)
3353 | INSERTED64(new_val, 32, 63)));
3354 break;
3355 case spr_dec:
3356 cpu_set_decrementer(processor, new_val);
3357 break;
3358 default:
3359 SPREG(n) = new_val;
3360 break;
3361 }
3362 }
3363 else {
3364 SPREG(n) = new_val;
3365 }
3366 }
3367 PPC_INSN_TO_SPR(RS_BITMASK, n);
3368
33690.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
3370*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3371*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3372*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3373*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3374 int n = (SPR{5:9} << 5) | SPR{0:4};
3375 if (SPR{0} && IS_PROBLEM_STATE(processor))
3376 program_interrupt(processor, cia,
3377 privileged_instruction_program_interrupt);
3378 else if (!spr_is_valid(n))
3379 program_interrupt(processor, cia,
3380 illegal_instruction_program_interrupt);
3381 else {
3382 /* HACK - time base registers need to be calculated */
3383 if (WITH_TIME_BASE) {
3384 switch (n) {
3385 case spr_dec:
3386 *rT = cpu_get_decrementer(processor);
3387 break;
3388 case spr_tbu:
3389 case spr_tbl:
3390 /* NOTE - these SPR's are not readable. Use mftb[ul] */
3391 default:
3392 *rT = SPREG(n);
3393 break;
3394 }
3395 }
3396 else {
3397 *rT = SPREG(n);
3398 }
3399 }
3400 PPC_INSN_FROM_SPR(RT_BITMASK, n);
3401
34020.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
3403*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3404*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3405*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3406*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
3407 if (FXM == 0xff) {
3408 CR = *rS;
3409 }
3410 else {
3411 unsigned_word mask = 0;
3412 unsigned_word f;
3413 for (f = 0; f < 8; f++) {
3414 if (FXM & (0x80 >> f))
3415 mask |= (0xf << 4*(7-f));
3416 }
3417 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3418 }
3419 PPC_INSN_MTCR(RS_BITMASK, FXM);
3420
34210.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
3422# CR_SET(BF, EXTRACTED32(XER, 0, 3));
3423# MBLIT32(XER, 0, 3, 0);
3424
34250.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
3426*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3427*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3428*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3429*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
3430 *rT = (unsigned32)CR;
3431 PPC_INSN_MFCR(RT_BITMASK);
3432
3433#
3434# I.4.6.2 Floating-Point Load Instructions
3435#
3436
34370.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
3438*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3439*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3440*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3441*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3442 unsigned_word b;
3443 unsigned_word EA;
3444 if (RA_is_0) b = 0;
3445 else b = *rA;
3446 EA = b + EXTS(D);
3447 *frT = DOUBLE(MEM(unsigned, EA, 4));
3448 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3449
34500.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
3451*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3452*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3453*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3454*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3455 unsigned_word b;
3456 unsigned_word EA;
3457 if (RA_is_0) b = 0;
3458 else b = *rA;
3459 EA = b + *rB;
3460 *frT = DOUBLE(MEM(unsigned, EA, 4));
3461 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3462
34630.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
3464*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3465*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3466*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3467*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3468 unsigned_word EA;
3469 if (RA_is_0)
3470 program_interrupt(processor, cia,
3471 illegal_instruction_program_interrupt);
3472 EA = *rA + EXTS(D);
3473 *frT = DOUBLE(MEM(unsigned, EA, 4));
3474 *rA = EA;
3475 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3476
ae02957b 34770.31,6.FRT,11.RA,16.RB,21.567,31./:X:f::Load Floating-Point Single with Update Indexed
c906108c
SS
3478*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3479*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3480*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3481*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3482 unsigned_word EA;
3483 if (RA_is_0)
3484 program_interrupt(processor, cia,
3485 illegal_instruction_program_interrupt);
3486 EA = *rA + *rB;
3487 *frT = DOUBLE(MEM(unsigned, EA, 4));
3488 *rA = EA;
3489 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3490
34910.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
3492*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3493*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3494*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3495*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3496 unsigned_word b;
3497 unsigned_word EA;
3498 if (RA_is_0) b = 0;
3499 else b = *rA;
3500 EA = b + EXTS(D);
3501 *frT = MEM(unsigned, EA, 8);
3502 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3503
35040.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
3505*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3506*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3507*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3508*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3509 unsigned_word b;
3510 unsigned_word EA;
3511 if (RA_is_0) b = 0;
3512 else b = *rA;
3513 EA = b + *rB;
3514 *frT = MEM(unsigned, EA, 8);
3515 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3516
35170.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
3518*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3519*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3520*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3521*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3522 unsigned_word EA;
3523 if (RA_is_0)
3524 program_interrupt(processor, cia,
3525 illegal_instruction_program_interrupt);
3526 EA = *rA + EXTS(D);
3527 *frT = MEM(unsigned, EA, 8);
3528 *rA = EA;
3529 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
3530
35310.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
3532*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3533*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3534*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3535*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3536 unsigned_word EA;
3537 if (RA_is_0)
3538 program_interrupt(processor, cia,
3539 illegal_instruction_program_interrupt);
3540 EA = *rA + *rB;
3541 *frT = MEM(unsigned, EA, 8);
3542 *rA = EA;
3543 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
3544
3545
3546#
3547# I.4.6.3 Floating-Point Store Instructions
3548#
3549
35500.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
3551*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3552*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3553*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3554*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3555 unsigned_word b;
3556 unsigned_word EA;
3557 if (RA_is_0) b = 0;
3558 else b = *rA;
3559 EA = b + EXTS(D);
3560 STORE(EA, 4, SINGLE(*frS));
3561 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3562
35630.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
3564*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3565*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3566*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3567*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3568 unsigned_word b;
3569 unsigned_word EA;
3570 if (RA_is_0) b = 0;
3571 else b = *rA;
3572 EA = b + *rB;
3573 STORE(EA, 4, SINGLE(*frS));
3574 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3575
35760.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
3577*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3578*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3579*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3580*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3581 unsigned_word EA;
3582 if (RA_is_0)
3583 program_interrupt(processor, cia,
3584 illegal_instruction_program_interrupt);
3585 EA = *rA + EXTS(D);
3586 STORE(EA, 4, SINGLE(*frS));
3587 *rA = EA;
3588 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3589
35900.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
3591*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3592*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3593*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3594*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3595 unsigned_word EA;
3596 if (RA_is_0)
3597 program_interrupt(processor, cia,
3598 illegal_instruction_program_interrupt);
3599 EA = *rA + *rB;
3600 STORE(EA, 4, SINGLE(*frS));
3601 *rA = EA;
3602 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3603
36040.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
3605*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3606*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3607*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3608*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3609 unsigned_word b;
3610 unsigned_word EA;
3611 if (RA_is_0) b = 0;
3612 else b = *rA;
3613 EA = b + EXTS(D);
3614 STORE(EA, 8, *frS);
3615 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3616
36170.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
3618*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3619*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3620*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3621*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3622 unsigned_word b;
3623 unsigned_word EA;
3624 if (RA_is_0) b = 0;
3625 else b = *rA;
3626 EA = b + *rB;
3627 STORE(EA, 8, *frS);
3628 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3629
36300.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
3631*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3632*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3633*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3634*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3635 unsigned_word EA;
3636 if (RA_is_0)
3637 program_interrupt(processor, cia,
3638 illegal_instruction_program_interrupt);
3639 EA = *rA + EXTS(D);
3640 STORE(EA, 8, *frS);
3641 *rA = EA;
3642 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
3643
36440.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
3645*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3646*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3647*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3648*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
3649 unsigned_word EA;
3650 if (RA_is_0)
3651 program_interrupt(processor, cia,
3652 illegal_instruction_program_interrupt);
3653 EA = *rA + *rB;
3654 STORE(EA, 8, *frS);
3655 *rA = EA;
3656 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
3657
3658
3659#
3660# I.4.6.4 Floating-Point Move Instructions
3661#
3662
36630.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
3664*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3665*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3666*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3667*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3668 *frT = *frB;
3669 CR1_UPDATE(Rc);
3670 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3671
36720.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
3673*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3674*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3675*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3676*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3677 *frT = *frB ^ BIT64(0);
3678 CR1_UPDATE(Rc);
3679 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3680
36810.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
3682*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3683*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3684*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3685*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3686 *frT = *frB & ~BIT64(0);
3687 CR1_UPDATE(Rc);
3688 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3689
36900.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
3691*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3692*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3693*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3694*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3695 *frT = *frB | BIT64(0);
3696 CR1_UPDATE(Rc);
3697 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
3698
3699
3700#
3701# I.4.6.5 Floating-Point Arithmetic Instructions
3702#
3703
37040.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
3705*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3706*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3707*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3708*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3709 FPSCR_BEGIN;
3710 if (is_invalid_operation(processor, cia,
3711 *frA, *frB,
3712 fpscr_vxsnan | fpscr_vxisi,
3713 0, /*single?*/
3714 0) /*negate?*/) {
3715 invalid_arithemetic_operation(processor, cia,
3716 frT, *frA, *frB, 0,
3717 0, /*instruction_is_frsp*/
3718 0, /*instruction_is_convert_to_64bit*/
3719 0, /*instruction_is_convert_to_32bit*/
3720 0); /*single-precision*/
3721 }
3722 else {
3723 /*HACK!*/
3724 double s = *(double*)frA + *(double*)frB;
3725 *(double*)frT = s;
3726 }
3727 FPSCR_END(Rc);
3728 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3729
37300.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
3731*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3732*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3733*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3734*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3735 FPSCR_BEGIN;
3736 if (is_invalid_operation(processor, cia,
3737 *frA, *frB,
3738 fpscr_vxsnan | fpscr_vxisi,
3739 1, /*single?*/
3740 0) /*negate?*/) {
3741 invalid_arithemetic_operation(processor, cia,
3742 frT, *frA, *frB, 0,
3743 0, /*instruction_is_frsp*/
3744 0, /*instruction_is_convert_to_64bit*/
3745 0, /*instruction_is_convert_to_32bit*/
3746 1); /*single-precision*/
3747 }
3748 else {
3749 /*HACK!*/
3750 float s = *(double*)frA + *(double*)frB;
3751 *(double*)frT = s;
3752 }
3753 FPSCR_END(Rc);
3754 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3755
37560.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
3757*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3758*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3759*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3760*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3761 FPSCR_BEGIN;
3762 if (is_invalid_operation(processor, cia,
3763 *frA, *frB,
3764 fpscr_vxsnan | fpscr_vxisi,
3765 0, /*single?*/
3766 1) /*negate?*/) {
3767 invalid_arithemetic_operation(processor, cia,
3768 frT, *frA, *frB, 0,
3769 0, /*instruction_is_frsp*/
3770 0, /*instruction_is_convert_to_64bit*/
3771 0, /*instruction_is_convert_to_32bit*/
3772 0); /*single-precision*/
3773 }
3774 else {
3775 /*HACK!*/
3776 double s = *(double*)frA - *(double*)frB;
3777 *(double*)frT = s;
3778 }
3779 FPSCR_END(Rc);
3780 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3781
37820.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
3783*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3784*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3785*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3786*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3787 FPSCR_BEGIN;
3788 if (is_invalid_operation(processor, cia,
3789 *frA, *frB,
3790 fpscr_vxsnan | fpscr_vxisi,
3791 1, /*single?*/
3792 1) /*negate?*/) {
3793 invalid_arithemetic_operation(processor, cia,
3794 frT, *frA, *frB, 0,
3795 0, /*instruction_is_frsp*/
3796 0, /*instruction_is_convert_to_64bit*/
3797 0, /*instruction_is_convert_to_32bit*/
3798 1); /*single-precision*/
3799 }
3800 else {
3801 /*HACK!*/
3802 float s = *(double*)frA - *(double*)frB;
3803 *(double*)frT = s;
3804 }
3805 FPSCR_END(Rc);
3806 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3807
38080.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
3809*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3810*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3811*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3812*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3813 FPSCR_BEGIN;
3814 if (is_invalid_operation(processor, cia,
3815 *frA, *frC,
3816 fpscr_vxsnan | fpscr_vximz,
3817 0, /*single?*/
3818 0) /*negate?*/) {
3819 invalid_arithemetic_operation(processor, cia,
3820 frT, *frA, 0, *frC,
3821 0, /*instruction_is_frsp*/
3822 0, /*instruction_is_convert_to_64bit*/
3823 0, /*instruction_is_convert_to_32bit*/
3824 0); /*single-precision*/
3825 }
3826 else {
3827 /*HACK!*/
3828 double s = *(double*)frA * *(double*)frC;
3829 *(double*)frT = s;
3830 }
3831 FPSCR_END(Rc);
3832 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3833
38340.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
3835*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3836*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3837*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3838*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3839 FPSCR_BEGIN;
3840 if (is_invalid_operation(processor, cia,
3841 *frA, *frC,
3842 fpscr_vxsnan | fpscr_vximz,
3843 1, /*single?*/
3844 0) /*negate?*/) {
3845 invalid_arithemetic_operation(processor, cia,
3846 frT, *frA, 0, *frC,
3847 0, /*instruction_is_frsp*/
3848 0, /*instruction_is_convert_to_64bit*/
3849 0, /*instruction_is_convert_to_32bit*/
3850 1); /*single-precision*/
3851 }
3852 else {
3853 /*HACK!*/
3854 float s = *(double*)frA * *(double*)frC;
3855 *(double*)frT = s;
3856 }
3857 FPSCR_END(Rc);
3858 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
3859
38600.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
3861*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3862*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3863*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3864*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
3865 FPSCR_BEGIN;
3866 if (is_invalid_operation(processor, cia,
3867 *frA, *frB,
3868 fpscr_vxsnan | fpscr_vxzdz,
3869 0, /*single?*/
3870 0) /*negate?*/) {
3871 invalid_arithemetic_operation(processor, cia,
3872 frT, *frA, *frB, 0,
3873 0, /*instruction_is_frsp*/
3874 0, /*instruction_is_convert_to_64bit*/
3875 0, /*instruction_is_convert_to_32bit*/
3876 0); /*single-precision*/
3877 }
3878 else if (is_invalid_zero_divide (processor, cia,
3879 *frA, *frB,
3880 0 /*single?*/)) {
3881 invalid_zero_divide_operation (processor, cia,
3882 frT, *frA, *frB,
3883 0 /*single?*/);
3884 }
3885 else {
3886 /*HACK!*/
3887 double s = *(double*)frA / *(double*)frB;
3888 *(double*)frT = s;
3889 }
3890 FPSCR_END(Rc);
3891 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3892
38930.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
3894*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3895*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3896*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3897*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3898 FPSCR_BEGIN;
3899 if (is_invalid_operation(processor, cia,
3900 *frA, *frB,
3901 fpscr_vxsnan | fpscr_vxzdz,
3902 1, /*single?*/
3903 0) /*negate?*/) {
3904 invalid_arithemetic_operation(processor, cia,
3905 frT, *frA, *frB, 0,
3906 0, /*instruction_is_frsp*/
3907 0, /*instruction_is_convert_to_64bit*/
3908 0, /*instruction_is_convert_to_32bit*/
3909 1); /*single-precision*/
3910 }
3911 else if (is_invalid_zero_divide (processor, cia,
3912 *frA, *frB,
3913 1 /*single?*/)) {
3914 invalid_zero_divide_operation (processor, cia,
3915 frT, *frA, *frB,
3916 1 /*single?*/);
3917 }
3918 else {
3919 /*HACK!*/
3920 float s = *(double*)frA / *(double*)frB;
3921 *(double*)frT = s;
3922 }
3923 FPSCR_END(Rc);
3924 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
3925
39260.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
3927*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3928*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3929*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3930*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3931 FPSCR_BEGIN;
3932 double product; /*HACK! - incorrectly loosing precision ... */
3933 /* compute the multiply */
3934 if (is_invalid_operation(processor, cia,
3935 *frA, *frC,
3936 fpscr_vxsnan | fpscr_vximz,
3937 0, /*single?*/
3938 0) /*negate?*/) {
3939 invalid_arithemetic_operation(processor, cia,
3940 (unsigned64*)&product, *frA, 0, *frC,
3941 0, /*instruction_is_frsp*/
3942 0, /*instruction_is_convert_to_64bit*/
3943 0, /*instruction_is_convert_to_32bit*/
3944 0); /*single-precision*/
3945 }
3946 else {
3947 /*HACK!*/
3948 product = *(double*)frA * *(double*)frC;
3949 }
3950 /* compute the add */
3951 if (is_invalid_operation(processor, cia,
3952 product, *frB,
3953 fpscr_vxsnan | fpscr_vxisi,
3954 0, /*single?*/
3955 0) /*negate?*/) {
3956 invalid_arithemetic_operation(processor, cia,
3957 frT, product, *frB, 0,
3958 0, /*instruction_is_frsp*/
3959 0, /*instruction_is_convert_to_64bit*/
3960 0, /*instruction_is_convert_to_32bit*/
3961 0); /*single-precision*/
3962 }
3963 else {
3964 /*HACK!*/
3965 double s = product + *(double*)frB;
3966 *(double*)frT = s;
3967 }
3968 FPSCR_END(Rc);
3969 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
3970
39710.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
3972*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3973*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3974*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3975*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3976 FPSCR_BEGIN;
3977 float product; /*HACK! - incorrectly loosing precision ... */
3978 /* compute the multiply */
3979 if (is_invalid_operation(processor, cia,
3980 *frA, *frC,
3981 fpscr_vxsnan | fpscr_vximz,
3982 1, /*single?*/
3983 0) /*negate?*/) {
3984 invalid_arithemetic_operation(processor, cia,
3985 (unsigned64*)&product, *frA, 0, *frC,
3986 0, /*instruction_is_frsp*/
3987 0, /*instruction_is_convert_to_64bit*/
3988 0, /*instruction_is_convert_to_32bit*/
3989 0); /*single-precision*/
3990 }
3991 else {
3992 /*HACK!*/
3993 product = *(double*)frA * *(double*)frC;
3994 }
3995 /* compute the add */
3996 if (is_invalid_operation(processor, cia,
3997 product, *frB,
3998 fpscr_vxsnan | fpscr_vxisi,
3999 1, /*single?*/
4000 0) /*negate?*/) {
4001 invalid_arithemetic_operation(processor, cia,
4002 frT, product, *frB, 0,
4003 0, /*instruction_is_frsp*/
4004 0, /*instruction_is_convert_to_64bit*/
4005 0, /*instruction_is_convert_to_32bit*/
4006 0); /*single-precision*/
4007 }
4008 else {
4009 /*HACK!*/
4010 float s = product + *(double*)frB;
4011 *(double*)frT = (double)s;
4012 }
4013 FPSCR_END(Rc);
4014 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4015
40160.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
4017*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4018*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4019*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4020*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4021 FPSCR_BEGIN;
4022 double product; /*HACK! - incorrectly loosing precision ... */
4023 /* compute the multiply */
4024 if (is_invalid_operation(processor, cia,
4025 *frA, *frC,
4026 fpscr_vxsnan | fpscr_vximz,
4027 0, /*single?*/
4028 0) /*negate?*/) {
4029 invalid_arithemetic_operation(processor, cia,
4030 (unsigned64*)&product, *frA, 0, *frC,
4031 0, /*instruction_is_frsp*/
4032 0, /*instruction_is_convert_to_64bit*/
4033 0, /*instruction_is_convert_to_32bit*/
4034 0); /*single-precision*/
4035 }
4036 else {
4037 /*HACK!*/
4038 product = *(double*)frA * *(double*)frC;
4039 }
4040 /* compute the subtract */
4041 if (is_invalid_operation(processor, cia,
4042 product, *frB,
4043 fpscr_vxsnan | fpscr_vxisi,
4044 0, /*single?*/
4045 0) /*negate?*/) {
4046 invalid_arithemetic_operation(processor, cia,
4047 frT, product, *frB, 0,
4048 0, /*instruction_is_frsp*/
4049 0, /*instruction_is_convert_to_64bit*/
4050 0, /*instruction_is_convert_to_32bit*/
4051 0); /*single-precision*/
4052 }
4053 else {
4054 /*HACK!*/
4055 double s = product - *(double*)frB;
4056 *(double*)frT = s;
4057 }
4058 FPSCR_END(Rc);
4059 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4060
40610.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
4062*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4063*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4064*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4065*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4066 FPSCR_BEGIN;
4067 float product; /*HACK! - incorrectly loosing precision ... */
4068 /* compute the multiply */
4069 if (is_invalid_operation(processor, cia,
4070 *frA, *frC,
4071 fpscr_vxsnan | fpscr_vximz,
4072 1, /*single?*/
4073 0) /*negate?*/) {
4074 invalid_arithemetic_operation(processor, cia,
4075 (unsigned64*)&product, *frA, 0, *frC,
4076 0, /*instruction_is_frsp*/
4077 0, /*instruction_is_convert_to_64bit*/
4078 0, /*instruction_is_convert_to_32bit*/
4079 0); /*single-precision*/
4080 }
4081 else {
4082 /*HACK!*/
4083 product = *(double*)frA * *(double*)frC;
4084 }
4085 /* compute the subtract */
4086 if (is_invalid_operation(processor, cia,
4087 product, *frB,
4088 fpscr_vxsnan | fpscr_vxisi,
4089 1, /*single?*/
4090 0) /*negate?*/) {
4091 invalid_arithemetic_operation(processor, cia,
4092 frT, product, *frB, 0,
4093 0, /*instruction_is_frsp*/
4094 0, /*instruction_is_convert_to_64bit*/
4095 0, /*instruction_is_convert_to_32bit*/
4096 0); /*single-precision*/
4097 }
4098 else {
4099 /*HACK!*/
4100 float s = product - *(double*)frB;
4101 *(double*)frT = (double)s;
4102 }
4103 FPSCR_END(Rc);
4104 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4105
41060.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
4107*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4108*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4109*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4110*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4111 FPSCR_BEGIN;
4112 double product; /*HACK! - incorrectly loosing precision ... */
4113 /* compute the multiply */
4114 if (is_invalid_operation(processor, cia,
4115 *frA, *frC,
4116 fpscr_vxsnan | fpscr_vximz,
4117 0, /*single?*/
4118 0) /*negate?*/) {
4119 invalid_arithemetic_operation(processor, cia,
4120 (unsigned64*)&product, *frA, 0, *frC,
4121 0, /*instruction_is_frsp*/
4122 0, /*instruction_is_convert_to_64bit*/
4123 0, /*instruction_is_convert_to_32bit*/
4124 0); /*single-precision*/
4125 }
4126 else {
4127 /*HACK!*/
4128 product = *(double*)frA * *(double*)frC;
4129 }
4130 /* compute the add */
4131 if (is_invalid_operation(processor, cia,
4132 product, *frB,
4133 fpscr_vxsnan | fpscr_vxisi,
4134 0, /*single?*/
4135 0) /*negate?*/) {
4136 invalid_arithemetic_operation(processor, cia,
4137 frT, product, *frB, 0,
4138 0, /*instruction_is_frsp*/
4139 0, /*instruction_is_convert_to_64bit*/
4140 0, /*instruction_is_convert_to_32bit*/
4141 0); /*single-precision*/
4142 }
4143 else {
4144 /*HACK!*/
4145 double s = -(product + *(double*)frB);
4146 *(double*)frT = s;
4147 }
4148 FPSCR_END(Rc);
4149 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4150
41510.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
4152*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4153*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4154*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4155*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4156 FPSCR_BEGIN;
4157 float product; /*HACK! - incorrectly loosing precision ... */
4158 /* compute the multiply */
4159 if (is_invalid_operation(processor, cia,
4160 *frA, *frC,
4161 fpscr_vxsnan | fpscr_vximz,
4162 1, /*single?*/
4163 0) /*negate?*/) {
4164 invalid_arithemetic_operation(processor, cia,
4165 (unsigned64*)&product, *frA, 0, *frC,
4166 0, /*instruction_is_frsp*/
4167 0, /*instruction_is_convert_to_64bit*/
4168 0, /*instruction_is_convert_to_32bit*/
4169 0); /*single-precision*/
4170 }
4171 else {
4172 /*HACK!*/
4173 product = *(double*)frA * *(double*)frC;
4174 }
4175 /* compute the add */
4176 if (is_invalid_operation(processor, cia,
4177 product, *frB,
4178 fpscr_vxsnan | fpscr_vxisi,
4179 1, /*single?*/
4180 0) /*negate?*/) {
4181 invalid_arithemetic_operation(processor, cia,
4182 frT, product, *frB, 0,
4183 0, /*instruction_is_frsp*/
4184 0, /*instruction_is_convert_to_64bit*/
4185 0, /*instruction_is_convert_to_32bit*/
4186 0); /*single-precision*/
4187 }
4188 else {
4189 /*HACK!*/
4190 float s = -(product + *(double*)frB);
4191 *(double*)frT = (double)s;
4192 }
4193 FPSCR_END(Rc);
4194 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4195
41960.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
4197*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
4198*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4199*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
4200*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4201 FPSCR_BEGIN;
4202 double product; /*HACK! - incorrectly loosing precision ... */
4203 /* compute the multiply */
4204 if (is_invalid_operation(processor, cia,
4205 *frA, *frC,
4206 fpscr_vxsnan | fpscr_vximz,
4207 0, /*single?*/
4208 0) /*negate?*/) {
4209 invalid_arithemetic_operation(processor, cia,
4210 (unsigned64*)&product, *frA, 0, *frC,
4211 0, /*instruction_is_frsp*/
4212 0, /*instruction_is_convert_to_64bit*/
4213 0, /*instruction_is_convert_to_32bit*/
4214 0); /*single-precision*/
4215 }
4216 else {
4217 /*HACK!*/
4218 product = *(double*)frA * *(double*)frC;
4219 }
4220 /* compute the subtract */
4221 if (is_invalid_operation(processor, cia,
4222 product, *frB,
4223 fpscr_vxsnan | fpscr_vxisi,
4224 0, /*single?*/
4225 0) /*negate?*/) {
4226 invalid_arithemetic_operation(processor, cia,
4227 frT, product, *frB, 0,
4228 0, /*instruction_is_frsp*/
4229 0, /*instruction_is_convert_to_64bit*/
4230 0, /*instruction_is_convert_to_32bit*/
4231 0); /*single-precision*/
4232 }
4233 else {
4234 /*HACK!*/
4235 double s = -(product - *(double*)frB);
4236 *(double*)frT = s;
4237 }
4238 FPSCR_END(Rc);
4239 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4240
42410.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
4242*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4243*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4244*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4245*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4246 FPSCR_BEGIN;
4247 float product; /*HACK! - incorrectly loosing precision ... */
4248 /* compute the multiply */
4249 if (is_invalid_operation(processor, cia,
4250 *frA, *frC,
4251 fpscr_vxsnan | fpscr_vximz,
4252 1, /*single?*/
4253 0) /*negate?*/) {
4254 invalid_arithemetic_operation(processor, cia,
4255 (unsigned64*)&product, *frA, 0, *frC,
4256 0, /*instruction_is_frsp*/
4257 0, /*instruction_is_convert_to_64bit*/
4258 0, /*instruction_is_convert_to_32bit*/
4259 0); /*single-precision*/
4260 }
4261 else {
4262 /*HACK!*/
4263 product = *(double*)frA * *(double*)frC;
4264 }
4265 /* compute the subtract */
4266 if (is_invalid_operation(processor, cia,
4267 product, *frB,
4268 fpscr_vxsnan | fpscr_vxisi,
4269 1, /*single?*/
4270 0) /*negate?*/) {
4271 invalid_arithemetic_operation(processor, cia,
4272 frT, product, *frB, 0,
4273 0, /*instruction_is_frsp*/
4274 0, /*instruction_is_convert_to_64bit*/
4275 0, /*instruction_is_convert_to_32bit*/
4276 0); /*single-precision*/
4277 }
4278 else {
4279 /*HACK!*/
4280 float s = -(product - *(double*)frB);
4281 *(double*)frT = (double)s;
4282 }
4283 FPSCR_END(Rc);
4284 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4285
4286
4287#
4288# I.4.6.6 Floating-Point Rounding and Conversion Instructions
4289#
4290
42910.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
4292*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4293*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4294*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4295*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4296 int sign;
4297 int exp;
4298 unsigned64 frac_grx;
4299 /***/
4300 /* split off cases for what to do */
4301 if (EXTRACTED64(*frB, 1, 11) < 897
4302 && EXTRACTED64(*frB, 1, 63) > 0) {
4303 if ((FPSCR & fpscr_ue) == 0) GOTO(Disabled_Exponent_Underflow);
4304 if ((FPSCR & fpscr_ue) != 0) GOTO(Enabled_Exponent_Underflow);
4305 }
4306 if (EXTRACTED64(*frB, 1, 11) > 1150
4307 && EXTRACTED64(*frB, 1, 11) < 2047) {
4308 if ((FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4309 if ((FPSCR & fpscr_oe) != 0) GOTO(Enabled_Exponent_Overflow);
4310 }
4311 if (EXTRACTED64(*frB, 1, 11) > 896
4312 && EXTRACTED64(*frB, 1, 11) < 1151) GOTO(Normal_Operand);
4313 if (EXTRACTED64(*frB, 1, 63) == 0) GOTO(Zero_Operand);
4314 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4315 if (EXTRACTED64(*frB, 12, 63) == 0) GOTO(Infinity_Operand);
4316 if (EXTRACTED64(*frB, 12, 12) == 1) GOTO(QNaN_Operand);
4317 if (EXTRACTED64(*frB, 12, 12) == 0
4318 && EXTRACTED64(*frB, 13, 63) > 0) GOTO(SNaN_Operand);
4319 }
4320 /**/
4321 LABEL(Disabled_Exponent_Underflow):
4322 sign = EXTRACTED64(*frB, 0, 0);
4323 if (EXTRACTED64(*frB, 1, 11) == 0) {
4324 exp = -1022;
4325 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4326 }
4327 if (EXTRACTED64(*frB, 1, 11) > 0) {
4328 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4329 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4330 }
4331 /* G|R|X == zero from above */
4332 while (exp < -126) {
9ff590a5 4333 exp = exp + 1;
c906108c
SS
4334 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4335 | MASKED64(frac_grx, 55, 55));
4336 }
4337 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4338 Round_Single(processor, sign, &exp, &frac_grx);
4339 FPSCR_SET_XX(FPSCR & fpscr_fi);
4340 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4341 *frT = INSERTED64(sign, 0, 0);
4342 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4343 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4344 }
4345 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4346 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4347 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4348 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4349 }
4350 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4351 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4352 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4353 }
4354 /*Normalize_Operand:*/
4355 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4356 exp = exp - 1;
4357 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4358 }
4359 *frT = (INSERTED64(sign, 0, 0)
4360 | INSERTED64(exp + 1023, 1, 11)
4361 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4362 }
4363 GOTO(Done);
4364 /**/
4365 LABEL(Enabled_Exponent_Underflow):
4366 FPSCR_SET_UX(1);
4367 sign = EXTRACTED64(*frB, 0, 0);
4368 if (EXTRACTED64(*frB, 1, 11) == 0) {
4369 exp = -1022;
4370 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4371 }
4372 if (EXTRACTED64(*frB, 1, 11) > 0) {
4373 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4374 frac_grx = (BIT64(0) |
4375 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4376 }
4377 /*Normalize_Operand:*/
4378 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4379 exp = exp - 1;
4380 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4381 }
4382 Round_Single(processor, sign, &exp, &frac_grx);
4383 FPSCR_SET_XX(FPSCR & fpscr_fi);
4384 exp = exp + 192;
4385 *frT = (INSERTED64(sign, 0, 0)
4386 | INSERTED64(exp + 1023, 1, 11)
4387 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4388 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4389 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4390 GOTO(Done);
4391 /**/
4392 LABEL(Disabled_Exponent_Overflow):
4393 FPSCR_SET_OX(1);
4394 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4395 if (EXTRACTED64(*frB, 0, 0) == 0) {
4396 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4397 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4398 }
4399 if (EXTRACTED64(*frB, 0, 0) == 1) {
4400 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4401 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4402 }
4403 }
4404 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4405 if (EXTRACTED64(*frB, 0, 0) == 0) {
4406 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4407 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4408 }
4409 if (EXTRACTED64(*frB, 0, 0) == 1) {
4410 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4411 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4412 }
4413 }
4414 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4415 if (EXTRACTED64(*frB, 0, 0) == 0) {
4416 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4417 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4418 }
4419 if (EXTRACTED64(*frB, 0, 0) == 1) {
4420 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4421 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4422 }
4423 }
4424 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4425 if (EXTRACTED64(*frB, 0, 0) == 0) {
4426 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4427 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4428 }
4429 if (EXTRACTED64(*frB, 0, 0) == 1) {
4430 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4431 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4432 }
4433 }
4434 /* FPSCR[FR] <- undefined */
4435 FPSCR_SET_FI(1);
4436 FPSCR_SET_XX(1);
4437 GOTO(Done);
4438 /**/
4439 LABEL(Enabled_Exponent_Overflow):
4440 sign = EXTRACTED64(*frB, 0, 0);
4441 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4442 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4443 Round_Single(processor, sign, &exp, &frac_grx);
4444 FPSCR_SET_XX(FPSCR & fpscr_fi);
4445 /**/
4446 LABEL(Enabled_Overflow):
4447 FPSCR_SET_OX(1);
4448 exp = exp - 192;
4449 *frT = (INSERTED64(sign, 0, 0)
4450 | INSERTED64(exp + 1023, 1, 11)
4451 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4452 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4453 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4454 GOTO(Done);
4455 /**/
4456 LABEL(Zero_Operand):
4457 *frT = *frB;
4458 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4459 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4460 FPSCR_SET_FR(0);
4461 FPSCR_SET_FI(0);
4462 GOTO(Done);
4463 /**/
4464 LABEL(Infinity_Operand):
4465 *frT = *frB;
4466 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4467 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4468 FPSCR_SET_FR(0);
4469 FPSCR_SET_FI(0);
4470 GOTO(Done);
4471 /**/
4472 LABEL(QNaN_Operand):
4473 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4474 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4475 FPSCR_SET_FR(0);
4476 FPSCR_SET_FI(0);
4477 GOTO(Done);
4478 /**/
4479 LABEL(SNaN_Operand):
4480 FPSCR_OR_VX(fpscr_vxsnan);
4481 if ((FPSCR & fpscr_ve) == 0) {
4482 *frT = (MASKED64(*frB, 0, 11)
4483 | BIT64(12)
4484 | MASKED64(*frB, 13, 34));
4485 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4486 }
4487 FPSCR_SET_FR(0);
4488 FPSCR_SET_FI(0);
4489 GOTO(Done);
4490 /**/
4491 LABEL(Normal_Operand):
4492 sign = EXTRACTED64(*frB, 0, 0);
4493 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4494 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4495 Round_Single(processor, sign, &exp, &frac_grx);
4496 FPSCR_SET_XX(FPSCR & fpscr_fi);
4497 if (exp > 127 && (FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow);
4498 if (exp > 127 && (FPSCR & fpscr_oe) != 0) GOTO(Enabled_Overflow);
4499 *frT = (INSERTED64(sign, 0, 0)
4500 | INSERTED64(exp + 1023, 1, 11)
4501 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4502 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4503 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4504 GOTO(Done);
4505 /**/
4506 LABEL(Done):
4507 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4508
4509
45100.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
4511 floating_point_assist_interrupt(processor, cia);
4512
45130.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
4514 floating_point_assist_interrupt(processor, cia);
4515
45160.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
4517 floating_point_assist_interrupt(processor, cia);
4518
45190.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
4520*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4521*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4522*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4523*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4524 FPSCR_BEGIN;
4525 convert_to_integer(processor, cia,
4526 frT, *frB,
4527 fpscr_rn_round_towards_zero, 32);
4528 FPSCR_END(Rc);
4529 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4530
45310.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4532 int sign = EXTRACTED64(*frB, 0, 0);
4533 int exp = 63;
4534 unsigned64 frac = *frB;
4535 /***/
4536 if (frac == 0) GOTO(Zero_Operand);
4537 if (sign == 1) frac = ~frac + 1;
4538 while (EXTRACTED64(frac, 0, 0) == 0) {
4539 /*??? do the loop 0 times if (FRB) = max negative integer */
4540 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4541 exp = exp - 1;
4542 }
4543 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4544 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4545 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4546 *frT = (INSERTED64(sign, 0, 0)
4547 | INSERTED64(exp + 1023, 1, 11)
4548 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4549 GOTO(Done);
4550 /**/
4551 LABEL(Zero_Operand):
4552 FPSCR_SET_FR(0);
4553 FPSCR_SET_FI(0);
4554 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4555 *frT = 0;
4556 GOTO(Done);
4557 /**/
4558 LABEL(Done):
4559 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4560
4561
4562#
4563# I.4.6.7 Floating-Point Compare Instructions
4564#
4565
45660.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
4567*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4568*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4569*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4570*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4571 FPSCR_BEGIN;
4572 unsigned c;
4573 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4574 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4575 else if (is_less_than(frA, frB))
4576 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4577 else if (is_greater_than(frA, frB))
4578 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4579 else
4580 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4581 FPSCR_SET_FPCC(c);
4582 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4583 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4584 FPSCR_OR_VX(fpscr_vxsnan);
4585 FPSCR_END(0);
4586 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4587
45880.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
4589*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4590*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4591*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4592*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4593 FPSCR_BEGIN;
4594 unsigned c;
4595 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4596 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4597 else if (is_less_than(frA, frB))
4598 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4599 else if (is_greater_than(frA, frB))
4600 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4601 else
4602 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4603 FPSCR_SET_FPCC(c);
4604 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4605 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4606 FPSCR_OR_VX(fpscr_vxsnan);
4607 if ((FPSCR & fpscr_ve) == 0)
4608 FPSCR_OR_VX(fpscr_vxvc);
4609 }
4610 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4611 FPSCR_OR_VX(fpscr_vxvc);
4612 }
4613 FPSCR_END(0);
4614 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
4615
4616
4617#
4618# I.4.6.8 Floating-Point Status and Control Register Instructions
4619#
4620
46210.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
4622 FPSCR_BEGIN;
4623 *frT = FPSCR;
4624 FPSCR_END(Rc);
4625
46260.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
4627 FPSCR_BEGIN;
4628 unsigned field = FPSCR_FIELD(BFA);
4629 CR_SET(BF, field);
4630 FPSCR_SET(BFA, 0); /* FPSCR_END fixes up FEX/VX */
4631 FPSCR_END(0);
4632
ec80ed80 46330.63,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
c906108c
SS
4634 FPSCR_BEGIN;
4635 FPSCR_SET(BF, U);
4636 FPSCR_END(Rc);
4637
46380.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
4639 FPSCR_BEGIN;
4640 int i;
4641 for (i = 0; i < 8; i++) {
4642 if ((FLM & BIT8(i))) {
4643 FPSCR &= ~MASK32(i*4, i*4+3);
4644 FPSCR |= MASKED32(*frB, i*4, i*4+3);
4645 }
4646 }
4647 FPSCR_END(Rc);
4648
46490.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
4650 FPSCR_BEGIN;
4651 unsigned32 bit = BIT32(BT);
4652 FPSCR &= ~bit;
4653 FPSCR_END(Rc);
4654
46550.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4656 FPSCR_BEGIN;
4657 unsigned32 bit = BIT32(BT);
4658 if (bit & fpscr_fi)
4659 bit |= fpscr_xx;
4660 if ((bit & fpscr_vx_bits))
4661 bit |= fpscr_fx;
4662 /* note - omit vx bit */
4663 if ((bit & (fpscr_ox | fpscr_ux | fpscr_zx | fpscr_xx)))
4664 bit |= fpscr_fx;
4665 FPSCR |= bit;
4666 FPSCR_END(Rc);
4667
4668
4669#
4670# I.A.1.1 Floating-Point Store Instruction
4671#
46720.31,6.FRS,11.RA,16.RB,21.983,31./:X:f,o::Store Floating-Point as Integer Word Indexed
4673 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4674
4675#
4676# I.A.1.2 Floating-Point Arithmetic Instructions
4677#
4678
46790.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root
4680 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4681
46820.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root Single
4683 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4684
46850.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f,o::Floating Reciprocal Estimate Single
4686 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4687
46880.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f,o::Floating Reciprocal Square Root Estimate
4689 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4690
4691#
4692# I.A.1.3 Floating-Point Select Instruction
4693#
4694
46950.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f,o::Floating Select
4696*601: PPC_UNIT_BAD, PPC_UNIT_BAD, 0, 0, 0
4697*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4698*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4699*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4700 if (CURRENT_MODEL == MODEL_ppc601) {
4701 program_interrupt(processor, cia, optional_instruction_program_interrupt);
4702 } else {
4703 unsigned64 zero = 0;
4704 FPSCR_BEGIN;
4705 if (is_NaN(*frA, 0) || is_less_than (frA, &zero)) *frT = *frB;
4706 else *frT = *frC;
4707 FPSCR_END(Rc);
4708 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4709 }
4710
4711#
4712# II.3.2 Cache Management Instructions
4713#
4714
47150.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
4716*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4717*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4718*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4719*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4720 /* blindly flush all instruction cache entries */
4721 #if WITH_IDECODE_CACHE_SIZE
4722 cpu_flush_icache(processor);
4723 #endif
4724 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
4725
47260.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
4727*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4728*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4729*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4730*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4731 cpu_synchronize_context(processor, cia);
4732 PPC_INSN_INT(0, 0, 0);
4733
4734
4735#
4736# II.3.2.2 Data Cache Instructions
4737#
4738
47390.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
4740*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4741*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4742*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4743*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4744 TRACE(trace_tbd,("Data Cache Block Touch\n"));
4745 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4746
47470.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
4748*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4749*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4750*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4751*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4752 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
4753 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4754
47550.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
4756*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4757*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4758*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4759*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4760 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
4761 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4762
47630.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
4764*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4765*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4766*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4767*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4768 TRACE(trace_tbd,("Data Cache Block Store\n"));
4769 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4770
47710.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
4772*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4773*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4774*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4775*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
4776 TRACE(trace_tbd,("Data Cache Block Flush\n"));
4777 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
4778
4779#
4780# II.3.3 Enforce In-order Execution of I/O Instruction
4781#
4782
47830.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4784 /* Since this model has no instruction overlap
4785 this instruction need do nothing */
4786
4787#
4788# II.4.1 Time Base Instructions
4789#
4790
47910.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
4792*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4793*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4794*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4795 int n = (tbr{5:9} << 5) | tbr{0:4};
4796 if (n == 268) {
4797 if (is_64bit_implementation) *rT = TB;
4798 else *rT = EXTRACTED64(TB, 32, 63);
4799 }
4800 else if (n == 269) {
4801 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4802 else *rT = EXTRACTED64(TB, 0, 31);
4803 }
4804 else
4805 program_interrupt(processor, cia,
4806 illegal_instruction_program_interrupt);
4807
4808
4809#
4810# III.2.3.1 System Linkage Instructions
4811#
4812
48130.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
4814*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4815*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4816*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4817*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4818 if (IS_PROBLEM_STATE(processor)) {
4819 program_interrupt(processor, cia,
4820 privileged_instruction_program_interrupt);
4821 }
4822 else {
4823 MSR = (MASKED(SRR1, 0, 32)
4824 | MASKED(SRR1, 37, 41)
4825 | MASKED(SRR1, 48, 63));
4826 NIA = MASKED(SRR0, 0, 61);
4827 cpu_synchronize_context(processor, cia);
4828 check_masked_interrupts(processor);
4829 }
4830
4831#
4832# III.3.4.1 Move to/from System Register Instructions
4833#
4834
4835#0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4836#0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
48370.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
4838*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4839*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4840*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4841*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4842 if (IS_PROBLEM_STATE(processor))
4843 program_interrupt(processor, cia,
4844 privileged_instruction_program_interrupt);
4845 else {
4846 MSR = *rS;
4847 check_masked_interrupts(processor);
4848 }
4849
48500.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
4851*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4852*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4853*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4854*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
4855 if (IS_PROBLEM_STATE(processor))
4856 program_interrupt(processor, cia,
4857 privileged_instruction_program_interrupt);
4858 else {
4859 *rT = MSR;
4860 check_masked_interrupts(processor);
4861 }
4862
4863
4864#
4865# III.4.11.1 Cache Management Instructions
4866#
4867
48680.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
4869*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4870*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4871*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4872*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4873 if (IS_PROBLEM_STATE(processor))
4874 program_interrupt(processor, cia,
4875 privileged_instruction_program_interrupt);
4876 else
4877 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
4878
4879#
4880# III.4.11.2 Segment Register Manipulation Instructions
4881#
4882
48830.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
4884*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4885*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4886*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4887*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4888 if (IS_PROBLEM_STATE(processor))
4889 program_interrupt(processor, cia,
4890 privileged_instruction_program_interrupt);
4891 else
4892 SEGREG(SR) = *rS;
4893
48940.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
4895*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4896*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4897*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4898*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4899 if (IS_PROBLEM_STATE(processor))
4900 program_interrupt(processor, cia,
4901 privileged_instruction_program_interrupt);
4902 else
4903 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
4904
49050.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
4906*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4907*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4908*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4909*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4910 if (IS_PROBLEM_STATE(processor))
4911 program_interrupt(processor, cia,
4912 privileged_instruction_program_interrupt);
4913 else
4914 *rT = SEGREG(SR);
4915
49160.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
4917*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4918*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4919*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4920*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
4921 if (IS_PROBLEM_STATE(processor))
4922 program_interrupt(processor, cia,
4923 privileged_instruction_program_interrupt);
4924 else
4925 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4926
4927
4928#
4929# III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4930#
4931
49320.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
4933
49340.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4935
49360.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
4937 if (IS_PROBLEM_STATE(processor))
4938 program_interrupt(processor, cia,
4939 privileged_instruction_program_interrupt);
4940 else {
4941 int nr = 0;
4942 cpu *proc;
4943 while (1) {
4944 proc = psim_cpu(cpu_system(processor), nr);
4945 if (proc == NULL) break;
4946 cpu_page_tlb_invalidate_entry(proc, *rB);
4947 nr++;
4948 }
4949 }
4950
49510.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4952 if (IS_PROBLEM_STATE(processor))
4953 program_interrupt(processor, cia,
4954 privileged_instruction_program_interrupt);
4955 else {
4956 int nr = 0;
4957 cpu *proc;
4958 while (1) {
4959 proc = psim_cpu(cpu_system(processor), nr);
4960 if (proc == NULL) break;
4961 cpu_page_tlb_invalidate_all(proc);
4962 nr++;
4963 }
4964 }
4965
49660.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
4967 /* nothing happens here - always in sync */
4968
4969#
4970# III.A.1.2 External Access Instructions
4971#
4972
49730.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
4974
49750.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
This page took 0.357336 seconds and 4 git commands to generate.