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