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