Remove missing file "PROBLEMS" from list of files to keep.
[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
4ffd6ed0 219 static 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
4ffd6ed0 231 static const char *const ppc_branch_conditional_name[32] = {
46c065ab
MM
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
4ffd6ed0 266 static const char *const ppc_nr_mtcrf_crs[9] = {
f2181eff
MM
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
4ffd6ed0
MM
1411#
1412# 0.0.0.0 Illegal instruction used for kernel mode emulation
1413#
14140.0,6./,11./,16./,21./,31.1:X:::instruction_call
1415 if (!os_emul_instruction_call(processor, cia, real_addr(cia, 1)))
1416 program_interrupt(processor, cia,
1417 illegal_instruction_program_interrupt);
1418
c143ef62
MM
1419#
1420# I.2.4.1 Branch Instructions
1421#
14220.18,6.LI,30.AA,31.LK:I:t::Branch
54e98699
MM
1423*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1424*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1425*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1426*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62
MM
1427 if (AA) NIA = IEA(EXTS(LI_0b00));
1428 else NIA = IEA(CIA + EXTS(LI_0b00));
1429 if (LK) LR = (spreg)CIA+4;
290ad14a 1430 if (CURRENT_MODEL_ISSUE > 0)
3d2f9d7c 1431 model_branches(cpu_model(processor), 1, -1);
84bbbc35 1432
c143ef62 14330.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
54e98699
MM
1434*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1435*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1436*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1437*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
84bbbc35 1438 int M, ctr_ok, cond_ok, succeed;
290ad14a 1439 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
54e98699 1440 model_wait_for_cr(cpu_model(processor), BIT32_BI);
c143ef62
MM
1441 if (is_64bit_implementation && is_64bit_mode) M = 0;
1442 else M = 32;
1443 if (!BO{2}) CTR = CTR - 1;
1444 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1445 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
84bbbc35 1446 if (ctr_ok && cond_ok) {
c143ef62
MM
1447 if (AA) NIA = IEA(EXTS(BD_0b00));
1448 else NIA = IEA(CIA + EXTS(BD_0b00));
84bbbc35
MM
1449 succeed = 1;
1450 }
1451 else
1452 succeed = 0;
c143ef62 1453 if (LK) LR = (spreg)IEA(CIA + 4);
290ad14a 1454 if (CURRENT_MODEL_ISSUE > 0)
3d2f9d7c 1455 model_branches(cpu_model(processor), succeed, BO);
84bbbc35
MM
1456 if (! BO{0}) {
1457 int reverse;
1458 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1459 reverse = EXTS(BD_0b00) < 0;
1460 } else { /* branch prediction bit not set */
1461 reverse = EXTS(BD_0b00) >= 0;
1462 }
290ad14a 1463 if (CURRENT_MODEL_ISSUE > 0)
3d2f9d7c 1464 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
84bbbc35
MM
1465 }
1466
c143ef62 14670.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
54e98699
MM
1468*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1469*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1470*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1471*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
84bbbc35 1472 int M, ctr_ok, cond_ok, succeed;
c143ef62
MM
1473 if (is_64bit_implementation && is_64bit_mode) M = 0;
1474 else M = 32;
290ad14a 1475 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
54e98699 1476 model_wait_for_cr(cpu_model(processor), BIT32_BI);
c143ef62
MM
1477 if (!BO{2}) CTR = CTR - 1;
1478 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1479 cond_ok = BO{0} || (CR{BI} == BO{1});
84bbbc35
MM
1480 if (ctr_ok && cond_ok) {
1481 NIA = IEA(LR_0b00);
1482 succeed = 1;
1483 }
1484 else
1485 succeed = 0;
c143ef62 1486 if (LK) LR = (spreg)IEA(CIA + 4);
290ad14a 1487 if (CURRENT_MODEL_ISSUE > 0) {
3d2f9d7c
MM
1488 model_branches(cpu_model(processor), succeed, BO);
1489 if (! BO{0})
1490 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1491 }
84bbbc35 1492
c143ef62 14930.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
54e98699
MM
1494*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1495*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1496*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1497*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
84bbbc35 1498 int cond_ok, succeed;
290ad14a 1499 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
54e98699 1500 model_wait_for_cr(cpu_model(processor), BIT32_BI);
c143ef62 1501 cond_ok = BO{0} || (CR{BI} == BO{1});
84bbbc35
MM
1502 if (cond_ok) {
1503 NIA = IEA(CTR_0b00);
1504 succeed = 1;
1505 }
1506 else
1507 succeed = 0;
c143ef62 1508 if (LK) LR = (spreg)IEA(CIA + 4);
290ad14a 1509 if (CURRENT_MODEL_ISSUE > 0) {
3d2f9d7c
MM
1510 model_branches(cpu_model(processor), succeed, BO);
1511 if (! BO{0})
1512 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1513 }
c143ef62
MM
1514
1515#
1516# I.2.4.2 System Call Instruction
1517#
15180.17,6./,11./,16./,30.1,31./:SC:t::System Call
54e98699
MM
1519*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1520*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1521*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1522*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
290ad14a 1523 if (CURRENT_MODEL_ISSUE > 0)
3d2f9d7c 1524 model_serialize(my_index, cpu_model(processor));
c143ef62
MM
1525 system_call_interrupt(processor, cia);
1526
1527#
1528# I.2.4.3 Condition Register Logical Instructions
1529#
15300.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
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.449,31./:XL::cror:Condition Register OR
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.193,31./:XL::crxor:Condition Register XOR
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.225,31./:XL::crnand:Condition Register NAND
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.33,31./:XL::crnor:Condition Register NOR
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.289,31./:XL::creqv:Condition Register Equivalent
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.129,31./:XL::crandc:Condition Register AND 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);
845ff5a4 1585
c143ef62 15860.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
54e98699
MM
1587*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1588*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1589*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1590*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1591 BLIT32(CR, BT, CR{BA} || !CR{BB});
f2181eff 1592 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
c143ef62
MM
1593
1594#
1595# I.2.4.4 Condition Register Field Instruction
1596#
15970.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
54e98699
MM
1598*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1599*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1600*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1601*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1602 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
f2181eff 1603 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
c143ef62
MM
1604
1605
1606#
1607# I.3.3.2 Fixed-Point Load Instructions
1608#
1609
16100.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
54e98699
MM
1611*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1612*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1613*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1614*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1615 unsigned_word b;
1616 unsigned_word EA;
1617 if (RA == 0) b = 0;
1618 else b = *rA;
1619 EA = b + EXTS(D);
1620 *rT = MEM(unsigned, EA, 1);
45525d8d 1621 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
54e98699 1622
845ff5a4 1623
c143ef62 16240.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
54e98699
MM
1625*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1626*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1627*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1628*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1629 unsigned_word b;
1630 unsigned_word EA;
1631 if (RA == 0) b = 0;
1632 else b = *rA;
1633 EA = b + *rB;
1634 *rT = MEM(unsigned, EA, 1);
45525d8d 1635 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 1636
c143ef62 16370.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
54e98699
MM
1638*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1639*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1640*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1641*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1642 unsigned_word EA;
1643 if (RA == 0 || RA == RT)
1644 program_interrupt(processor, cia,
1645 illegal_instruction_program_interrupt);
1646 EA = *rA + EXTS(D);
1647 *rT = MEM(unsigned, EA, 1);
1648 *rA = EA;
45525d8d 1649 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1650
c143ef62 16510.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
54e98699
MM
1652*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1653*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1654*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1655*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1656 unsigned_word EA;
1657 if (RA == 0 || RA == RT)
1658 program_interrupt(processor, cia,
1659 illegal_instruction_program_interrupt);
1660 EA = *rA + *rB;
1661 *rT = MEM(unsigned, EA, 1);
1662 *rA = EA;
45525d8d 1663 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1664
16650.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
54e98699
MM
1666*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1667*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1668*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1669*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1670 unsigned_word b;
1671 unsigned_word EA;
1672 if (RA == 0) b = 0;
1673 else b = *rA;
1674 EA = b + EXTS(D);
1675 *rT = MEM(unsigned, EA, 2);
45525d8d 1676 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 1677
c143ef62 16780.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
54e98699
MM
1679*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1680*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1681*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1682*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1683 unsigned_word b;
1684 unsigned_word EA;
1685 if (RA == 0) b = 0;
1686 else b = *rA;
1687 EA = b + *rB;
1688 *rT = MEM(unsigned, EA, 2);
45525d8d 1689 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
54e98699 1690
c143ef62 16910.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
54e98699
MM
1692*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1693*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1694*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1695*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1696 unsigned_word EA;
1697 if (RA == 0 || RA == RT)
1698 program_interrupt(processor, cia,
1699 illegal_instruction_program_interrupt);
1700 EA = *rA + EXTS(D);
1701 *rT = MEM(unsigned, EA, 2);
1702 *rA = EA;
45525d8d 1703 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1704
c143ef62 17050.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
54e98699
MM
1706*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1707*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1708*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1709*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1710 unsigned_word EA;
1711 if (RA == 0 || RA == RT)
1712 program_interrupt(processor, cia,
1713 illegal_instruction_program_interrupt);
1714 EA = *rA + *rB;
1715 *rT = MEM(unsigned, EA, 2);
1716 *rA = EA;
45525d8d 1717 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1718
17190.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
54e98699
MM
1720*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1721*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1722*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1723*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1724 unsigned_word b;
1725 unsigned_word EA;
1726 if (RA == 0) b = 0;
1727 else b = *rA;
1728 EA = b + EXTS(D);
1729 *rT = MEM(signed, EA, 2);
45525d8d 1730 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 1731
c143ef62 17320.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
54e98699
MM
1733*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1734*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1735*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1736*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1737 unsigned_word b;
1738 unsigned_word EA;
1739 if (RA == 0) b = 0;
1740 else b = *rA;
1741 EA = b + *rB;
1742 *rT = MEM(signed, EA, 2);
45525d8d 1743 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 1744
c143ef62 17450.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
54e98699
MM
1746*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1747*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1748*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1749*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1750 unsigned_word EA;
1751 if (RA == 0 || RA == RT)
1752 program_interrupt(processor, cia,
1753 illegal_instruction_program_interrupt);
1754 EA = *rA + EXTS(D);
1755 *rT = MEM(signed, EA, 2);
45525d8d 1756 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1757
c143ef62 17580.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
54e98699
MM
1759*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1760*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1761*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1762*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1763 unsigned_word EA;
1764 if (RA == 0 || RA == RT)
1765 program_interrupt(processor, cia,
1766 illegal_instruction_program_interrupt);
1767 EA = *rA + *rB;
1768 *rT = MEM(signed, EA, 2);
1769 *rA = EA;
45525d8d 1770 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1771
17720.32,6.RT,11.RA,16.D:D:::Load Word and Zero
54e98699
MM
1773*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1774*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1775*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1776*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1777 unsigned_word b;
1778 unsigned_word EA;
1779 if (RA == 0) b = 0;
1780 else b = *rA;
1781 EA = b + EXTS(D);
1782 *rT = MEM(unsigned, EA, 4);
45525d8d 1783 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 1784
c143ef62 17850.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
54e98699
MM
1786*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1787*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1788*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1789*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1790 unsigned_word b;
1791 unsigned_word EA;
1792 if (RA == 0) b = 0;
1793 else b = *rA;
1794 EA = b + *rB;
1795 *rT = MEM(unsigned, EA, 4);
45525d8d 1796 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 1797
c143ef62 17980.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
54e98699
MM
1799*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1800*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1801*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1802*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1803 unsigned_word EA;
1804 if (RA == 0 || RA == RT)
1805 program_interrupt(processor, cia,
1806 illegal_instruction_program_interrupt);
1807 EA = *rA + EXTS(D);
1808 *rT = MEM(unsigned, EA, 4);
1809 *rA = EA;
45525d8d 1810 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1811
c143ef62 18120.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
54e98699
MM
1813*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1814*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1815*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1816*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1817 unsigned_word EA;
1818 if (RA == 0 || RA == RT)
1819 program_interrupt(processor, cia,
1820 illegal_instruction_program_interrupt);
1821 EA = *rA + *rB;
1822 *rT = MEM(unsigned, EA, 4);
1823 *rA = EA;
45525d8d 1824 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1825
18260.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1827# unsigned_word b;
1828# unsigned_word EA;
1829# if (RA == 0) b = 0;
1830# else b = *rA;
1831# EA = b + EXTS(DS_0b00);
1832# *rT = MEM(signed, EA, 4);
845ff5a4 1833
c143ef62
MM
18340.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1835# unsigned_word b;
1836# unsigned_word EA;
1837# if (RA == 0) b = 0;
1838# else b = *rA;
1839# EA = b + *rB;;
1840# *rT = MEM(signed, EA, 4);
845ff5a4 1841
c143ef62
MM
18420.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1843# unsigned_word EA;
1844# if (RA == 0 || RA == RT)
1845# program_interrupt(processor, cia
1846# illegal_instruction_program_interrupt);
1847# EA = *rA + *rB;
1848# *rT = MEM(signed, EA, 4);
1849# *rA = EA;
1850
18510.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1852# unsigned_word b;
1853# unsigned_word EA;
1854# if (RA == 0) b = 0;
1855# else b = *rA;
1856# EA = b + EXTS(DS_0b00);
1857# *rT = MEM(unsigned, EA, 8);
845ff5a4 1858
c143ef62
MM
18590.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1860# unsigned_word b;
1861# unsigned_word EA;
1862# if (RA == 0) b = 0;
1863# else b = *rA;
1864# EA = b + *rB;
1865# *rT = MEM(unsigned, EA, 8);
845ff5a4 1866
c143ef62
MM
18670.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1868# unsigned_word EA;
1869# if (RA == 0 || RA == RT)
1870# program_interrupt(processor, cia
1871# illegal_instruction_program_interrupt);
1872# EA = *rA + EXTS(DS_0b00);
1873# *rT = MEM(unsigned, EA, 8);
1874# *rA = EA;
845ff5a4 1875
c143ef62
MM
18760.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1877# unsigned_word EA;
1878# if (RA == 0 || RA == RT)
1879# program_interrupt(processor, cia
1880# illegal_instruction_program_interrupt);
1881# EA = *rA + *rB;
1882# *rT = MEM(unsigned, EA, 8);
1883# *rA = EA;
1884
1885
1886
1887#
1888# I.3.3.3 Fixed-Point Store Instructions
1889#
1890
18910.38,6.RS,11.RA,16.D:D:::Store Byte
54e98699
MM
1892*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1893*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1894*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1895*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1896 unsigned_word b;
1897 unsigned_word EA;
1898 if (RA == 0) b = 0;
1899 else b = *rA;
1900 EA = b + EXTS(D);
1901 STORE(EA, 1, *rS);
45525d8d 1902 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
845ff5a4 1903
c143ef62 19040.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
54e98699
MM
1905*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1906*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1907*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1908*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1909 unsigned_word b;
1910 unsigned_word EA;
1911 if (RA == 0) b = 0;
1912 else b = *rA;
1913 EA = b + *rB;
1914 STORE(EA, 1, *rS);
45525d8d 1915 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 1916
c143ef62 19170.39,6.RS,11.RA,16.D:D:::Store Byte with Update
54e98699
MM
1918*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1919*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1920*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1921*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1922 unsigned_word EA;
1923 if (RA == 0)
1924 program_interrupt(processor, cia,
1925 illegal_instruction_program_interrupt);
1926 EA = *rA + EXTS(D);
1927 STORE(EA, 1, *rS);
1928 *rA = EA;
45525d8d 1929 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
845ff5a4 1930
c143ef62 19310.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
54e98699
MM
1932*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1933*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1934*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1935*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1936 unsigned_word EA;
1937 if (RA == 0)
1938 program_interrupt(processor, cia,
1939 illegal_instruction_program_interrupt);
1940 EA = *rA + *rB;
1941 STORE(EA, 1, *rS);
1942 *rA = EA;
45525d8d 1943 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
1944
19450.44,6.RS,11.RA,16.D:D:::Store Half Word
54e98699
MM
1946*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1947*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1948*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1949*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1950 unsigned_word b;
1951 unsigned_word EA;
1952 if (RA == 0) b = 0;
1953 else b = *rA;
1954 EA = b + EXTS(D);
1955 STORE(EA, 2, *rS);
45525d8d 1956 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
845ff5a4 1957
c143ef62 19580.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
54e98699
MM
1959*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1960*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1961*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1962*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1963 unsigned_word b;
1964 unsigned_word EA;
1965 if (RA == 0) b = 0;
1966 else b = *rA;
1967 EA = b + *rB;
1968 STORE(EA, 2, *rS);
45525d8d 1969 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 1970
c143ef62 19710.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
54e98699
MM
1972*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1973*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1974*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1975*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1976 unsigned_word EA;
1977 if (RA == 0)
1978 program_interrupt(processor, cia,
1979 illegal_instruction_program_interrupt);
1980 EA = *rA + EXTS(D);
1981 STORE(EA, 2, *rS);
1982 *rA = EA;
45525d8d 1983 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
845ff5a4 1984
c143ef62 19850.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
54e98699
MM
1986*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1987*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1988*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1989*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1990 unsigned_word EA;
1991 if (RA == 0)
1992 program_interrupt(processor, cia,
1993 illegal_instruction_program_interrupt);
1994 EA = *rA + *rB;
1995 STORE(EA, 2, *rS);
1996 *rA = EA;
45525d8d 1997 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
1998
19990.36,6.RS,11.RA,16.D:D:::Store Word
54e98699
MM
2000*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2001*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2002*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2003*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
2004 unsigned_word b;
2005 unsigned_word EA;
2006 if (RA == 0) b = 0;
2007 else b = *rA;
2008 EA = b + EXTS(D);
2009 STORE(EA, 4, *rS);
45525d8d 2010 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
845ff5a4 2011
c143ef62 20120.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
54e98699
MM
2013*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2014*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2015*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2016*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
2017 unsigned_word b;
2018 unsigned_word EA;
2019 if (RA == 0) b = 0;
2020 else b = *rA;
2021 EA = b + *rB;
2022 STORE(EA, 4, *rS);
45525d8d 2023 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 2024
c143ef62 20250.37,6.RS,11.RA,16.D:D:::Store Word with Update
54e98699
MM
2026*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2027*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2028*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2029*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
2030 unsigned_word EA;
2031 if (RA == 0)
2032 program_interrupt(processor, cia,
2033 illegal_instruction_program_interrupt);
2034 EA = *rA + EXTS(D);
2035 STORE(EA, 4, *rS);
2036 *rA = EA;
45525d8d 2037 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
845ff5a4 2038
c143ef62 20390.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
54e98699
MM
2040*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2041*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2042*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2043*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
2044 unsigned_word EA;
2045 if (RA == 0)
2046 program_interrupt(processor, cia,
2047 illegal_instruction_program_interrupt);
2048 EA = *rA + *rB;
2049 STORE(EA, 4, *rS);
2050 *rA = EA;
45525d8d 2051 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
2052
20530.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2054# unsigned_word b;
2055# unsigned_word EA;
2056# if (RA == 0) b = 0;
2057# else b = *rA;
2058# EA = b + EXTS(DS_0b00);
2059# STORE(EA, 8, *rS);
20600.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2061# unsigned_word b;
2062# unsigned_word EA;
2063# if (RA == 0) b = 0;
2064# else b = *rA;
2065# EA = b + *rB;
2066# STORE(EA, 8, *rS);
20670.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2068# unsigned_word EA;
2069# if (RA == 0)
2070# program_interrupt(processor, cia
2071# illegal_instruction_program_interrupt);
2072# EA = *rA + EXTS(DS_0b00);
2073# STORE(EA, 8, *rS);
2074# *rA = EA;
20750.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2076# unsigned_word EA;
2077# if (RA == 0)
2078# program_interrupt(processor, cia
2079# illegal_instruction_program_interrupt);
2080# EA = *rA + *rB;
2081# STORE(EA, 8, *rS);
2082# *rA = EA;
2083
2084
2085#
2086# I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2087#
2088
20890.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
54e98699
MM
2090*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2091*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2092*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2093*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2094 unsigned_word b;
2095 unsigned_word EA;
2096 if (RA == 0) b = 0;
2097 else b = *rA;
2098 EA = b + *rB;
2099 *rT = SWAP_2(MEM(unsigned, EA, 2));
45525d8d 2100 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 2101
c143ef62 21020.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
54e98699
MM
2103*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2104*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2105*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2106*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2107 unsigned_word b;
2108 unsigned_word EA;
2109 if (RA == 0) b = 0;
2110 else b = *rA;
2111 EA = b + *rB;
2112 *rT = SWAP_4(MEM(unsigned, EA, 4));
45525d8d 2113 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
2114
21150.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
54e98699
MM
2116*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2117*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2118*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2119*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2120 unsigned_word b;
2121 unsigned_word EA;
2122 if (RA == 0) b = 0;
2123 else b = *rA;
2124 EA = b + *rB;
2125 STORE(EA, 2, SWAP_2(*rS));
45525d8d 2126 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 2127
c143ef62 21280.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
54e98699
MM
2129*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2130*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2131*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2132*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2133 unsigned_word b;
2134 unsigned_word EA;
2135 if (RA == 0) b = 0;
2136 else b = *rA;
2137 EA = b + *rB;
2138 STORE(EA, 4, SWAP_4(*rS));
45525d8d 2139 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
2140
2141
2142#
2143# I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2144#
2145
21460.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
845ff5a4 2147
c143ef62
MM
21480.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2149
2150
2151#
2152# I.3.3.6 Fixed-Point Move Assist Instructions
2153#
2154
21550.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
845ff5a4 2156
c143ef62
MM
21570.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2158
21590.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
845ff5a4 2160
c143ef62
MM
21610.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2162
2163
2164#
2165# I.3.3.7 Storage Synchronization Instructions
2166#
2167# HACK: Rather than monitor addresses looking for a reason
2168# to cancel a reservation. This code instead keeps
2169# a copy of the data read from memory. Before performing
2170# a store, the memory area is checked to see if it has
2171# been changed.
21720.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
54e98699
MM
2173*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2174*603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2175*603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2176*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
2177 unsigned_word b;
2178 unsigned_word EA;
2179 if (RA == 0) b = 0;
2180 else b = *rA;
2181 EA = b + *rB;
2182 RESERVE = 1;
2183 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2184 RESERVE_DATA = MEM(unsigned, EA, 4);
2185 *rT = RESERVE_DATA;
45525d8d 2186 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 2187
c143ef62
MM
21880.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2189 unsigned_word b;
2190 unsigned_word EA;
2191 if (RA == 0) b = 0;
2192 else b = *rA;
2193 EA = b + *rB;
2194 RESERVE = 1;
2195 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2196 RESERVE_DATA = MEM(unsigned, EA, 8);
2197 *rT = RESERVE_DATA;
45525d8d 2198 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
2199
22000.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
54e98699
MM
2201*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2202*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2203*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2204*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
c143ef62
MM
2205 unsigned_word b;
2206 unsigned_word EA;
2207 if (RA == 0) b = 0;
2208 else b = *rA;
2209 EA = b + *rB;
2210 if (RESERVE) {
2211 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2212 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2213 STORE(EA, 4, *rS);
2214 CR_SET_XER_SO(0, cr_i_zero);
2215 }
2216 else {
2217 /* ment to randomly to store, we never do! */
2218 CR_SET_XER_SO(0, 0);
2219 }
2220 RESERVE = 0;
2221 }
2222 else {
2223 CR_SET_XER_SO(0, 0);
2224 }
45525d8d
MM
2225 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2226
c143ef62
MM
22270.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2228 unsigned_word b;
2229 unsigned_word EA;
2230 if (RA == 0) b = 0;
2231 else b = *rA;
2232 EA = b + *rB;
2233 if (RESERVE) {
2234 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2235 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2236 STORE(EA, 8, *rS);
2237 CR_SET_XER_SO(0, cr_i_zero);
2238 }
2239 else {
2240 /* ment to randomly to store, we never do */
2241 CR_SET_XER_SO(0, 0);
2242 }
2243 RESERVE = 0;
2244 }
2245 else {
2246 CR_SET_XER_SO(0, 0);
2247 }
45525d8d 2248 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
c143ef62
MM
2249
22500.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
54e98699
MM
2251*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2252*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2253*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2254*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
c143ef62
MM
2255 /* do nothing */
2256
2257
2258#
2259# I.3.3.9 Fixed-Point Arithmetic Instructions
2260#
2261
22620.14,6.RT,11.RA,16.SI:D:T::Add Immediate
54e98699
MM
2263*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2264*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2265*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2266*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
45525d8d
MM
2267 if (RA_is_0) *rT = EXTS(SI);
2268 else *rT = *rA + EXTS(SI);
4ffd6ed0 2269 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
45525d8d 2270 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
80948f39 2271
c143ef62 22720.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
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
45525d8d
MM
2277 if (RA_is_0) *rT = EXTS(SI) << 16;
2278 else *rT = *rA + (EXTS(SI) << 16);
4ffd6ed0 2279 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
45525d8d 2280 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
80948f39 2281
c143ef62 22820.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
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_SRU, 1, 1, 0
2286*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2287 ALU_BEGIN(*rA);
2288 ALU_ADD(*rB);
2289 ALU_END(*rT, 0/*CA*/, OE, Rc);
45525d8d 2290 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2291
c143ef62 22920.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
54e98699
MM
2293*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2294*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2295*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2296*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2297 ALU_BEGIN(*rA);
2298 ALU_NOT;
2299 ALU_ADD(*rB);
2300 ALU_ADD(1);
2301 ALU_END(*rT, 0/*CA*/, OE, Rc);
45525d8d 2302 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2303
c143ef62 23040.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
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*/, 0/*Rc*/);
45525d8d 2312 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
80948f39 2313
c143ef62 23140.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
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_ADD(EXTS(SI));
2321 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
45525d8d 2322 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
80948f39 2323
c143ef62 23240.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
54e98699
MM
2325*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2326*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2327*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2328*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2329 ALU_BEGIN(*rA);
2330 ALU_NOT;
2331 ALU_ADD(EXTS(SI));
2332 ALU_ADD(1);
2333 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
45525d8d 2334 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
80948f39 2335
c143ef62 23360.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add 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 ALU_BEGIN(*rA);
2342 ALU_ADD(*rB);
2343 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2344 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2345
c143ef62 23460.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
54e98699
MM
2347*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2348*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2349*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2350*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2351 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2352 ALU_BEGIN(*rA);
2353 ALU_NOT;
2354 ALU_ADD(*rB);
2355 ALU_ADD(1);
2356 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2357 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2358
c143ef62 23590.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
54e98699
MM
2360*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2361*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2362*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2363*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2364 ALU_BEGIN(*rA);
2365 ALU_ADD(*rB);
2366 ALU_ADD_CA;
2367 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2368 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2369
c143ef62 23700.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
54e98699
MM
2371*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2372*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2373*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2374*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2375 ALU_BEGIN(*rA);
2376 ALU_NOT;
2377 ALU_ADD(*rB);
2378 ALU_ADD_CA;
2379 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2380 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2381
c143ef62 23820.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to 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
4ffd6ed0
MM
2387 ALU_BEGIN(*rA);
2388 ALU_ADD_CA;
2389 ALU_ADD(-1);
2390 ALU_END(*rT, 1/*CA*/, OE, Rc);
2391 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2392
c143ef62 23930.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One 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
4ffd6ed0
MM
2398 ALU_BEGIN(*rA);
2399 ALU_NOT;
2400 ALU_ADD_CA;
2401 ALU_ADD(-1);
2402 ALU_END(*rT, 1/*CA*/, OE, Rc);
2403 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2404
c143ef62 24050.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
54e98699
MM
2406*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2407*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2408*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2409*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2410 ALU_BEGIN(*rA);
2411 ALU_ADD_CA;
2412 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2413 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2414
c143ef62 24150.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
54e98699
MM
2416*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2417*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2418*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2419*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2420 ALU_BEGIN(*rA);
2421 ALU_NOT;
2422 ALU_ADD_CA;
2423 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2424 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2425
c143ef62 24260.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
54e98699
MM
2427*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2428*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2429*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2430*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2431 ALU_BEGIN(*rA);
2432 ALU_NOT;
2433 ALU_ADD(1);
2434 ALU_END(*rT,0/*CA*/,OE,Rc);
45525d8d 2435 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2436
c143ef62 24370.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
54e98699
MM
2438*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2439*603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2440*603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2441*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62
MM
2442 signed_word prod = *rA * EXTS(SI);
2443 *rT = prod;
45525d8d 2444 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
80948f39 2445
c143ef62 24460.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
80948f39 2447
c143ef62 24480.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
54e98699
MM
2449*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2450*603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2451*603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2452*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
c143ef62
MM
2453 signed64 a = (signed32)(*rA);
2454 signed64 b = (signed32)(*rB);
2455 signed64 prod = a * b;
2456 signed_word t = prod;
2457 *rT = *rA * *rB;
2458 if (t != prod && OE)
2459 XER |= (xer_overflow | xer_summary_overflow);
2460 CR0_COMPARE(t, 0, Rc);
45525d8d 2461 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2462
c143ef62 24630.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
80948f39 2464
c143ef62 24650.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
54e98699
MM
2466*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2467*603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2468*603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2469*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
c143ef62
MM
2470 signed64 a = (signed32)(*rA);
2471 signed64 b = (signed32)(*rB);
2472 signed64 prod = a * b;
2473 signed_word t = EXTRACTED64(prod, 0, 31);
2474 *rT = t;
2475 CR0_COMPARE(t, 0, Rc);
45525d8d 2476 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2477
c143ef62 24780.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
80948f39 2479
c143ef62 24800.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
54e98699
MM
2481*601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2482*603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2483*603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2484*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
c143ef62
MM
2485 unsigned64 a = (unsigned32)(*rA);
2486 unsigned64 b = (unsigned32)(*rB);
2487 unsigned64 prod = a * b;
2488 signed_word t = EXTRACTED64(prod, 0, 31);
2489 *rT = t;
2490 CR0_COMPARE(t, 0, Rc);
45525d8d 2491 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2492
c143ef62 24930.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
80948f39 2494
c143ef62 24950.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
54e98699
MM
2496*601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2497*603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2498*603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2499*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
c143ef62
MM
2500 signed64 dividend = (signed32)(*rA);
2501 signed64 divisor = (signed32)(*rB);
2502 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2503 || (dividend == 0x80000000 && divisor == -1)) {
2504 if (OE)
2505 XER |= (xer_overflow | xer_summary_overflow);
2506 CR0_COMPARE(0, 0, Rc);
2507 }
2508 else {
2509 signed64 quotent = dividend / divisor;
2510 *rT = quotent;
2511 CR0_COMPARE((signed_word)quotent, 0, Rc);
2512 }
45525d8d 2513 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
54e98699 2514
c143ef62 25150.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
80948f39 2516
c143ef62 25170.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
54e98699
MM
2518*601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2519*603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2520*603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2521*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
c143ef62
MM
2522 unsigned64 dividend = (unsigned32)(*rA);
2523 unsigned64 divisor = (unsigned32)(*rB);
2524 if (divisor == 0) {
2525 if (OE)
2526 XER |= (xer_overflow | xer_summary_overflow);
2527 CR0_COMPARE(0, 0, Rc);
2528 }
2529 else {
2530 unsigned64 quotent = dividend / divisor;
2531 *rT = quotent;
2532 CR0_COMPARE((signed_word)quotent, 0, Rc);
2533 }
45525d8d 2534 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
c143ef62
MM
2535
2536
2537#
2538# I.3.3.10 Fixed-Point Compare Instructions
2539#
2540
25410.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
54e98699
MM
2542*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2543*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2544*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2545*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2546 if (!is_64bit_mode && L)
2547 program_interrupt(processor, cia,
2548 illegal_instruction_program_interrupt);
2549 else {
2550 signed_word a;
2551 signed_word b = EXTS(SI);
2552 if (L == 0)
2553 a = EXTENDED(*rA);
2554 else
2555 a = *rA;
2556 CR_COMPARE(BF, a, b);
2557 }
45525d8d 2558 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
845ff5a4 2559
c143ef62 25600.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
54e98699
MM
2561*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2562*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2563*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2564*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2565 if (!is_64bit_mode && L)
2566 program_interrupt(processor, cia,
2567 illegal_instruction_program_interrupt);
2568 else {
2569 signed_word a;
2570 signed_word b;
2571 if (L == 0) {
2572 a = EXTENDED(*rA);
2573 b = EXTENDED(*rB);
2574 }
2575 else {
2576 a = *rA;
2577 b = *rB;
2578 }
2579 CR_COMPARE(BF, a, b);
2580 }
45525d8d 2581 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
845ff5a4 2582
c143ef62 25830.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
54e98699
MM
2584*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2585*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2586*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2587*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2588 if (!is_64bit_mode && L)
2589 program_interrupt(processor, cia,
2590 illegal_instruction_program_interrupt);
2591 else {
2592 unsigned_word a;
2593 unsigned_word b = UI;
2594 if (L == 0)
2595 a = MASKED(*rA, 32, 63);
2596 else
2597 a = *rA;
2598 CR_COMPARE(BF, a, b);
2599 }
45525d8d 2600 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
845ff5a4 2601
c143ef62 26020.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
54e98699
MM
2603*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2604*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2605*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2606*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2607 if (!is_64bit_mode && L)
2608 program_interrupt(processor, cia,
2609 illegal_instruction_program_interrupt);
2610 else {
2611 unsigned_word a;
2612 unsigned_word b;
2613 if (L == 0) {
2614 a = MASKED(*rA, 32, 63);
2615 b = MASKED(*rB, 32, 63);
2616 }
2617 else {
2618 a = *rA;
2619 b = *rB;
2620 }
2621 CR_COMPARE(BF, a, b);
2622 }
45525d8d 2623 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
c143ef62
MM
2624
2625
2626#
2627# I.3.3.11 Fixed-Point Trap Instructions
2628#
2629
26300.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2631 if (!is_64bit_mode)
2632 program_interrupt(processor, cia,
2633 illegal_instruction_program_interrupt);
2634 else {
2635 signed_word a = *rA;
2636 signed_word b = EXTS(SI);
2637 if ((a < b && TO{0})
2638 || (a > b && TO{1})
2639 || (a == b && TO{2})
2640 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2641 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2642 )
2643 program_interrupt(processor, cia,
2644 trap_program_interrupt);
2645 }
845ff5a4 2646
c143ef62 26470.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
54e98699
MM
2648*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2649*603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2650*603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2651*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2652 signed_word a = EXTENDED(*rA);
2653 signed_word b = EXTS(SI);
2654 if ((a < b && TO{0})
2655 || (a > b && TO{1})
2656 || (a == b && TO{2})
2657 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2658 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2659 )
2660 program_interrupt(processor, cia,
2661 trap_program_interrupt);
845ff5a4 2662
c143ef62
MM
26630.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2664 if (!is_64bit_mode)
2665 program_interrupt(processor, cia,
2666 illegal_instruction_program_interrupt);
2667 else {
2668 signed_word a = *rA;
2669 signed_word b = *rB;
2670 if ((a < b && TO{0})
2671 || (a > b && TO{1})
2672 || (a == b && TO{2})
2673 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2674 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2675 )
2676 program_interrupt(processor, cia,
2677 trap_program_interrupt);
2678 }
845ff5a4 2679
c143ef62 26800.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
54e98699
MM
2681*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2682*603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2683*603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2684*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2685 signed_word a = EXTENDED(*rA);
2686 signed_word b = EXTENDED(*rB);
2687 if (TO == 12 && rA == rB) {
2688 ITRACE(trace_breakpoint, ("breakpoint\n"));
2689 cpu_halt(processor, cia, was_trap, 0);
2690 }
2691 else if ((a < b && TO{0})
2692 || (a > b && TO{1})
2693 || (a == b && TO{2})
2694 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2695 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2696 )
2697 program_interrupt(processor, cia,
2698 trap_program_interrupt);
2699
2700#
2701# I.3.3.12 Fixed-Point Logical Instructions
2702#
2703
27040.28,6.RS,11.RA,16.UI:D:::AND Immediate
54e98699
MM
2705*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2706*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2707*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2708*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2709 *rA = *rS & UI;
2710 CR0_COMPARE(*rA, 0, 1/*Rc*/);
4ffd6ed0 2711 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2712 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
845ff5a4 2713
c143ef62 27140.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
54e98699
MM
2715*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2716*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2717*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2718*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2719 *rA = *rS & (UI << 16);
2720 CR0_COMPARE(*rA, 0, 1/*Rc*/);
4ffd6ed0 2721 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2722 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
845ff5a4 2723
c143ef62 27240.24,6.RS,11.RA,16.UI:D:::OR Immediate
54e98699
MM
2725*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2726*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2727*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2728*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62 2729 *rA = *rS | UI;
4ffd6ed0 2730 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2731 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2732
c143ef62 27330.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
54e98699
MM
2734*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2735*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2736*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2737*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62 2738 *rA = *rS | (UI << 16);
4ffd6ed0 2739 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2740 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2741
c143ef62 27420.26,6.RS,11.RA,16.UI:D:::XOR Immediate
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 2747 *rA = *rS ^ UI;
4ffd6ed0 2748 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2749 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2750
c143ef62 27510.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
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 2756 *rA = *rS ^ (UI << 16);
4ffd6ed0 2757 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2758 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2759
c143ef62 27600.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
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);
4ffd6ed0 2767 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2768 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2769
c143ef62 27700.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
54e98699
MM
2771*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2772*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2773*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2774*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2775 *rA = *rS | *rB;
2776 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2777 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2778 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2779
c143ef62 27800.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
54e98699
MM
2781*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2782*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2783*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2784*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2785 *rA = *rS ^ *rB;
2786 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2787 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2788 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2789
c143ef62 27900.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
54e98699
MM
2791*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2792*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2793*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2794*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2795 *rA = ~(*rS & *rB);
2796 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2797 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2798 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2799
c143ef62 28000.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
54e98699
MM
2801*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2802*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2803*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2804*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2805 *rA = ~(*rS | *rB);
2806 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2807 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2808 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2809
c143ef62 28100.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
54e98699
MM
2811*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2812*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2813*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2814*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
4ffd6ed0
MM
2815 *rA = ~(*rS ^ *rB); /* A === B */
2816 CR0_COMPARE(*rA, 0, Rc);
2817 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2818 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2819
c143ef62 28200.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
54e98699
MM
2821*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2822*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2823*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2824*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2825 *rA = *rS & ~*rB;
2826 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2827 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2828 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
54e98699 2829
c143ef62 28300.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
54e98699
MM
2831*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2832*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2833*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2834*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2835 *rA = *rS | ~*rB;
2836 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2837 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2838 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2839
c143ef62 28400.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
54e98699
MM
2841*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2842*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2843*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2844*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2845 *rA = (signed_word)(signed8)*rS;
2846 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2847 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2848 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 2849
c143ef62 28500.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half 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 *rA = (signed_word)(signed16)*rS;
2856 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2857 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2858 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 2859
c143ef62 28600.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
54e98699
MM
2861*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2862*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2863*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2864*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2865# *rA = (signed_word)(signed32)*rS;
2866# CR0_COMPARE(*rA, 0, Rc);
845ff5a4 2867
c143ef62
MM
28680.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2869# int count = 0;
2870# unsigned64 mask = BIT64(0);
2871# unsigned64 source = *rS;
2872# while (!(source & mask) && mask != 0) {
2873# mask >>= 1;
2874# count++;
2875# }
2876# *rA = count;
2877# CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
845ff5a4 2878
c143ef62 28790.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
54e98699
MM
2880*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2881*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2882*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2883*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2884 int count = 0;
2885 unsigned32 mask = BIT32(0);
2886 unsigned32 source = *rS;
2887 while (!(source & mask) && mask != 0) {
2888 mask >>= 1;
2889 count++;
2890 }
2891 *rA = count;
4ffd6ed0 2892 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
c143ef62
MM
2893 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2894
2895
2896#
2897# I.3.3.13 Fixed-Point Rotate and Shift Instructions
2898#
2899
29000.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
2901# long n = (sh_5 << 4) | sh_0_4;
2902# unsigned_word r = ROTL64(*rS, n);
2903# long b = (mb_5 << 4) | mb_0_4;
2904# unsigned_word m = MASK(b, 63);
2905# signed_word result = r & m;
2906# *rA = result;
4ffd6ed0 2907# ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
c143ef62 2908# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
845ff5a4 2909
c143ef62
MM
29100.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
2911# long n = (sh_5 << 4) | sh_0_4;
2912# unsigned_word r = ROTL64(*rS, n);
2913# long e = (me_5 << 4) | me_0_4;
2914# unsigned_word m = MASK(0, e);
2915# signed_word result = r & m;
2916# *rA = result;
2917# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
845ff5a4 2918
c143ef62
MM
29190.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
2920# long n = (sh_5 << 4) | sh_0_4;
2921# unsigned_word r = ROTL64(*rS, n);
2922# long b = (mb_5 << 4) | mb_0_4;
2923# unsigned_word m = MASK(0, (64-n));
2924# signed_word result = r & m;
2925# *rA = result;
2926# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2927
29280.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
54e98699
MM
2929*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2930*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2931*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2932*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2933 long n = SH;
2934 unsigned32 s = *rS;
2935 unsigned32 r = ROTL32(s, n);
2936 unsigned32 m = MASK(MB+32, ME+32);
2937 signed_word result = r & m;
2938 *rA = result;
2939 CR0_COMPARE(result, 0, Rc);
2940 ITRACE(trace_alu,
45525d8d
MM
2941 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
2942 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
2943 (unsigned long)result, (unsigned long)CR));
2944 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
2945
29460.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2947# long n = MASKED(*rB, 58, 63);
2948# unsigned_word r = ROTL64(*rS, n);
2949# long b = (mb_5 << 4) | mb_0_4;
2950# unsigned_word m = MASK(b, 63);
2951# signed_word result = r & m;
2952# *rA = result;
2953# CR0_COMPARE(result, 0, Rc);
845ff5a4 2954
c143ef62
MM
29550.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2956# long n = MASKED(*rB, 58, 63);
2957# unsigned_word r = ROTL64(*rS, n);
2958# long e = (me_5 << 4) | me_0_4;
2959# unsigned_word m = MASK(0, e);
2960# signed_word result = r & m;
2961# *rA = result;
2962# CR0_COMPARE(result, 0, Rc);
2963
29640.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2965# long n = MASKED(*rB, 59, 63);
2966# unsigned32 r = ROTL32(*rS, n);
2967# unsigned32 m = MASK(MB+32, ME+32);
2968# signed_word result = r & m;
2969# *rA = result;
2970# CR0_COMPARE(result, 0, Rc);
845ff5a4 2971
c143ef62
MM
29720.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
2973# long n = (sh_5 << 4) | sh_0_4;
2974# unsigned_word r = ROTL64(*rS, n);
2975# long b = (mb_5 << 4) | mb_0_4;
2976# unsigned_word m = MASK(b, (64-n));
2977# signed_word result = (r & m) | (*rA & ~m)
2978# *rA = result;
2979# CR0_COMPARE(result, 0, Rc);
845ff5a4 2980
c143ef62 29810.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
54e98699
MM
2982*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2983*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2984*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2985*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2986 long n = SH;
2987 unsigned32 r = ROTL32(*rS, n);
2988 unsigned32 m = MASK(MB+32, ME+32);
2989 signed_word result = (r & m) | (*rA & ~m);
2990 *rA = result;
45525d8d
MM
2991 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
2992 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
2993 (unsigned long)result));
c143ef62 2994 CR0_COMPARE(result, 0, Rc);
45525d8d 2995 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
2996
2997
29980.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
845ff5a4 2999
c143ef62 30000.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
54e98699
MM
3001*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3002*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3003*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3004*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
3005 int n = MASKED(*rB, 59, 63);
3006 unsigned32 source = *rS;
3007 signed_word shifted;
3008 if (n < 32)
3009 shifted = (source << n);
3010 else
3011 shifted = 0;
3012 *rA = shifted;
3013 CR0_COMPARE(shifted, 0, Rc);
3014 ITRACE(trace_alu,
45525d8d
MM
3015 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3016 n, (unsigned long)source, (unsigned long)shifted));
3017 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 3018
c143ef62 30190.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
845ff5a4 3020
c143ef62 30210.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
54e98699
MM
3022*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3023*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3024*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3025*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
3026 int n = MASKED(*rB, 59, 63);
3027 unsigned32 source = *rS;
3028 signed_word shifted;
3029 if (n < 32)
3030 shifted = (source >> n);
3031 else
3032 shifted = 0;
3033 *rA = shifted;
3034 CR0_COMPARE(shifted, 0, Rc);
3035 ITRACE(trace_alu, \
45525d8d
MM
3036 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3037 n, (unsigned long)source, (unsigned long)shifted));
3038 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
3039
30400.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
845ff5a4 3041
c143ef62 30420.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
54e98699
MM
3043*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3044*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3045*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3046*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
3047 int n = SH;
3048 signed_word r = ROTL32(*rS, /*64*/32-n);
3049 signed_word m = MASK(n+32, 63);
3050 int S = MASKED(*rS, 32, 32);
3051 signed_word shifted = (r & m) | (S ? ~m : 0);
3052 *rA = shifted;
3053 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3054 XER |= xer_carry;
3055 else
3056 XER &= ~xer_carry;
3057 CR0_COMPARE(shifted, 0, Rc);
4ffd6ed0
MM
3058 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3059 (long)*rA, (long)*rA, (long)XER));
45525d8d 3060 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 3061
c143ef62 30620.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
845ff5a4 3063
c143ef62 30640.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
54e98699
MM
3065*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3066*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3067*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3068*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
3069 int n = MASKED(*rB, 58, 63);
3070 int shift = (n >= 31 ? 31 : n);
3071 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3072 signed32 shifted = source >> shift;
3073 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
3074 *rA = (signed_word)shifted; /* if 64bit will sign extend */
3075 if (source < 0 && (source & mask))
3076 XER |= xer_carry;
3077 else
3078 XER &= ~xer_carry;
3079 CR0_COMPARE(shifted, 0, Rc);
4ffd6ed0
MM
3080 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3081 (long)*rA, (long)*rA, (long)XER));
45525d8d 3082 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
3083
3084#
3085# I.3.3.14 Move to/from System Register Instructions
3086#
3087
f2181eff 30880.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
54e98699
MM
3089*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3090*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3091*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3092*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
f2181eff
MM
3093 int n = (SPR{5:9} << 5) | SPR{0:4};
3094 if (SPR{0} && IS_PROBLEM_STATE(processor))
c143ef62
MM
3095 program_interrupt(processor, cia,
3096 privileged_instruction_program_interrupt);
3097 else if (!spr_is_valid(n)
3098 || spr_is_readonly(n))
3099 program_interrupt(processor, cia,
3100 illegal_instruction_program_interrupt);
3101 else {
3102 spreg new_val = (spr_length(n) == 64
3103 ? *rS
3104 : MASKED(*rS, 32, 63));
3105 /* HACK - time base registers need to be updated immediatly */
3106 if (WITH_TIME_BASE) {
c143ef62
MM
3107 switch (n) {
3108 case spr_tbu:
3109 cpu_set_time_base(processor,
80948f39
MM
3110 (MASKED64(cpu_get_time_base(processor), 32, 63)
3111 | INSERTED64(new_val, 0, 31)));
c143ef62
MM
3112 break;
3113 case spr_tbl:
3114 cpu_set_time_base(processor,
80948f39
MM
3115 (MASKED64(cpu_get_time_base(processor), 0, 31)
3116 | INSERTED64(new_val, 32, 63)));
c143ef62
MM
3117 break;
3118 case spr_dec:
3119 cpu_set_decrementer(processor, new_val);
3120 break;
3121 default:
3122 SPREG(n) = new_val;
3123 break;
3124 }
3125 }
3126 else {
3127 SPREG(n) = new_val;
3128 }
3129 }
45525d8d 3130 PPC_INSN_TO_SPR(RS_BITMASK, n);
845ff5a4 3131
f2181eff 31320.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
54e98699
MM
3133*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3134*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3135*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3136*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
f2181eff
MM
3137 int n = (SPR{5:9} << 5) | SPR{0:4};
3138 if (SPR{0} && IS_PROBLEM_STATE(processor))
c143ef62
MM
3139 program_interrupt(processor, cia,
3140 privileged_instruction_program_interrupt);
3141 else if (!spr_is_valid(n))
3142 program_interrupt(processor, cia,
3143 illegal_instruction_program_interrupt);
3144 else {
3145 /* HACK - some SPR's need to get their value extracted specially */
3146 *rT = SPREG(n);
3147 }
45525d8d 3148 PPC_INSN_FROM_SPR(RT_BITMASK, n);
845ff5a4 3149
c143ef62 31500.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
54e98699
MM
3151*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3152*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3153*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3154*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
3155 if (FXM == 0xff) {
3156 CR = *rS;
3157 }
3158 else {
3159 unsigned_word mask = 0;
3160 unsigned_word f;
3161 for (f = 0; f < 8; f++) {
3162 if (FXM & (0x80 >> f))
3163 mask |= (0xf << 4*(7-f));
3164 }
3165 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3166 }
f2181eff 3167 PPC_INSN_MTCR(RS_BITMASK, FXM);
845ff5a4 3168
c143ef62 31690.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
845ff5a4 3170
c143ef62 31710.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
54e98699
MM
3172*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3173*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3174*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3175*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62 3176 *rT = (unsigned32)CR;
45525d8d 3177 PPC_INSN_MFCR(RT_BITMASK);
c143ef62
MM
3178
3179#
3180# I.4.6.2 Floating-Point Load Instructions
3181#
3182
31830.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
54e98699
MM
3184*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3185*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3186*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3187*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3188 unsigned_word b;
3189 unsigned_word EA;
3190 if (RA == 0) b = 0;
3191 else b = *rA;
3192 EA = b + EXTS(D);
3193 *frT = DOUBLE(MEM(unsigned, EA, 4));
45525d8d 3194 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3195
c143ef62 31960.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
54e98699
MM
3197*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3198*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3199*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3200*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3201 unsigned_word b;
3202 unsigned_word EA;
3203 if (RA == 0) b = 0;
3204 else b = *rA;
3205 EA = b + *rB;
3206 *frT = DOUBLE(MEM(unsigned, EA, 4));
45525d8d 3207 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 3208
c143ef62 32090.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
54e98699
MM
3210*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3211*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3212*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3213*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3214 unsigned_word EA;
3215 if (RA == 0)
3216 program_interrupt(processor, cia,
3217 illegal_instruction_program_interrupt);
3218 EA = *rA + EXTS(D);
3219 *frT = DOUBLE(MEM(unsigned, EA, 4));
3220 *rA = EA;
45525d8d 3221 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3222
c143ef62 32230.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
54e98699
MM
3224*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3225*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3226*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3227*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3228 unsigned_word EA;
3229 if (RA == 0)
3230 program_interrupt(processor, cia,
3231 illegal_instruction_program_interrupt);
3232 EA = *rA + *rB;
3233 *frT = DOUBLE(MEM(unsigned, EA, 4));
3234 *rA = EA;
45525d8d 3235 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
3236
32370.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
54e98699
MM
3238*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3239*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3240*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3241*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3242 unsigned_word b;
3243 unsigned_word EA;
3244 if (RA == 0) b = 0;
3245 else b = *rA;
3246 EA = b + EXTS(D);
3247 *frT = MEM(unsigned, EA, 8);
45525d8d 3248 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3249
c143ef62 32500.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
54e98699
MM
3251*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3252*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3253*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3254*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3255 unsigned_word b;
3256 unsigned_word EA;
3257 if (RA == 0) b = 0;
3258 else b = *rA;
3259 EA = b + *rB;
3260 *frT = MEM(unsigned, EA, 8);
45525d8d 3261 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 3262
c143ef62 32630.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
54e98699
MM
3264*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3265*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3266*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3267*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3268 unsigned_word EA;
3269 if (RA == 0)
3270 program_interrupt(processor, cia,
3271 illegal_instruction_program_interrupt);
3272 EA = *rA + EXTS(D);
3273 *frT = MEM(unsigned, EA, 8);
3274 *rA = EA;
45525d8d 3275 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3276
c143ef62 32770.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
54e98699
MM
3278*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3279*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3280*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3281*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3282 unsigned_word EA;
3283 if (RA == 0)
3284 program_interrupt(processor, cia,
3285 illegal_instruction_program_interrupt);
3286 EA = *rA + *rB;
3287 *frT = MEM(unsigned, EA, 8);
3288 *rA = EA;
45525d8d 3289 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
3290
3291
3292#
3293# I.4.6.3 Floating-Point Store Instructions
3294#
3295
32960.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
54e98699
MM
3297*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3298*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3299*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3300*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3301 unsigned_word b;
3302 unsigned_word EA;
3303 if (RA == 0) b = 0;
3304 else b = *rA;
3305 EA = b + EXTS(D);
3306 STORE(EA, 4, SINGLE(*frS));
45525d8d 3307 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3308
c143ef62 33090.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
54e98699
MM
3310*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3311*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3312*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3313*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3314 unsigned_word b;
3315 unsigned_word EA;
3316 if (RA == 0) b = 0;
3317 else b = *rA;
3318 EA = b + *rB;
3319 STORE(EA, 4, SINGLE(*frS));
45525d8d 3320 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
845ff5a4 3321
c143ef62 33220.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
54e98699
MM
3323*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3324*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3325*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3326*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3327 unsigned_word EA;
3328 if (RA == 0)
3329 program_interrupt(processor, cia,
3330 illegal_instruction_program_interrupt);
3331 EA = *rA + EXTS(D);
3332 STORE(EA, 4, SINGLE(*frS));
3333 *rA = EA;
45525d8d 3334 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3335
c143ef62 33360.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
54e98699
MM
3337*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3338*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3339*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3340*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3341 unsigned_word EA;
3342 if (RA == 0)
3343 program_interrupt(processor, cia,
3344 illegal_instruction_program_interrupt);
3345 EA = *rA + *rB;
3346 STORE(EA, 4, SINGLE(*frS));
3347 *rA = EA;
45525d8d 3348 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
c143ef62
MM
3349
33500.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
54e98699
MM
3351*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3352*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3353*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3354*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3355 unsigned_word b;
3356 unsigned_word EA;
3357 if (RA == 0) b = 0;
3358 else b = *rA;
3359 EA = b + EXTS(D);
3360 STORE(EA, 8, *frS);
45525d8d 3361 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3362
c143ef62 33630.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
54e98699
MM
3364*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3365*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3366*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3367*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3368 unsigned_word b;
3369 unsigned_word EA;
3370 if (RA == 0) b = 0;
3371 else b = *rA;
3372 EA = b + *rB;
3373 STORE(EA, 8, *frS);
45525d8d 3374 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
845ff5a4 3375
c143ef62 33760.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
54e98699
MM
3377*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3378*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3379*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3380*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3381 unsigned_word EA;
3382 if (RA == 0)
3383 program_interrupt(processor, cia,
3384 illegal_instruction_program_interrupt);
3385 EA = *rA + EXTS(D);
3386 STORE(EA, 8, *frS);
3387 *rA = EA;
45525d8d 3388 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3389
c143ef62 33900.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
54e98699
MM
3391*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3392*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3393*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3394*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3395 unsigned_word EA;
3396 if (RA == 0)
3397 program_interrupt(processor, cia,
3398 illegal_instruction_program_interrupt);
3399 EA = *rA + *rB;
3400 STORE(EA, 8, *frS);
3401 *rA = EA;
45525d8d 3402 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
c143ef62
MM
3403
3404
3405#
3406# I.4.6.4 Floating-Point Move Instructions
3407#
3408
34090.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
54e98699
MM
3410*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3411*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3412*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3413*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3414 *frT = *frB;
3415 CR1_UPDATE(Rc);
45525d8d 3416 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 3417
c143ef62 34180.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
54e98699
MM
3419*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3420*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3421*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3422*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3423 *frT = *frB ^ BIT64(0);
3424 CR1_UPDATE(Rc);
45525d8d 3425 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 3426
c143ef62 34270.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
54e98699
MM
3428*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3429*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3430*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3431*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3432 *frT = *frB & ~BIT64(0);
3433 CR1_UPDATE(Rc);
45525d8d 3434 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 3435
c143ef62 34360.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
54e98699
MM
3437*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3438*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3439*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3440*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3441 *frT = *frB | BIT64(0);
3442 CR1_UPDATE(Rc);
45525d8d 3443 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
c143ef62
MM
3444
3445
3446#
3447# I.4.6.5 Floating-Point Arithmetic Instructions
3448#
3449
34500.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
54e98699
MM
3451*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3452*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3453*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3454*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3455 FPSCR_BEGIN;
3456 if (is_invalid_operation(processor, cia,
3457 *frA, *frB,
3458 fpscr_vxsnan | fpscr_vxisi,
3459 0, /*single?*/
3460 0) /*negate?*/) {
3461 invalid_arithemetic_operation(processor, cia,
3462 frT, *frA, *frB, 0,
3463 0, /*instruction_is_frsp*/
3464 0, /*instruction_is_convert_to_64bit*/
3465 0, /*instruction_is_convert_to_32bit*/
3466 0); /*single-precision*/
3467 }
3468 else {
3469 /*HACK!*/
3470 double s = *(double*)frA + *(double*)frB;
3471 *(double*)frT = s;
3472 }
3473 FPSCR_END(Rc);
45525d8d 3474 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
845ff5a4 3475
c143ef62 34760.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
54e98699
MM
3477*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3478*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3479*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3480*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3481 FPSCR_BEGIN;
3482 if (is_invalid_operation(processor, cia,
3483 *frA, *frB,
3484 fpscr_vxsnan | fpscr_vxisi,
3485 1, /*single?*/
3486 0) /*negate?*/) {
3487 invalid_arithemetic_operation(processor, cia,
3488 frT, *frA, *frB, 0,
3489 0, /*instruction_is_frsp*/
3490 0, /*instruction_is_convert_to_64bit*/
3491 0, /*instruction_is_convert_to_32bit*/
3492 1); /*single-precision*/
3493 }
3494 else {
3495 /*HACK!*/
3496 float s = *(double*)frA + *(double*)frB;
3497 *(double*)frT = s;
3498 }
3499 FPSCR_END(Rc);
45525d8d 3500 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
c143ef62
MM
3501
35020.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
54e98699
MM
3503*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3504*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3505*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3506*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3507 FPSCR_BEGIN;
3508 if (is_invalid_operation(processor, cia,
3509 *frA, *frB,
3510 fpscr_vxsnan | fpscr_vxisi,
3511 0, /*single?*/
3512 1) /*negate?*/) {
3513 invalid_arithemetic_operation(processor, cia,
3514 frT, *frA, *frB, 0,
3515 0, /*instruction_is_frsp*/
3516 0, /*instruction_is_convert_to_64bit*/
3517 0, /*instruction_is_convert_to_32bit*/
3518 0); /*single-precision*/
3519 }
3520 else {
3521 /*HACK!*/
3522 double s = *(double*)frA - *(double*)frB;
3523 *(double*)frT = s;
3524 }
3525 FPSCR_END(Rc);
45525d8d 3526 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
845ff5a4 3527
c143ef62 35280.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
54e98699
MM
3529*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3530*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3531*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3532*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3533 FPSCR_BEGIN;
3534 if (is_invalid_operation(processor, cia,
3535 *frA, *frB,
3536 fpscr_vxsnan | fpscr_vxisi,
3537 1, /*single?*/
3538 1) /*negate?*/) {
3539 invalid_arithemetic_operation(processor, cia,
3540 frT, *frA, *frB, 0,
3541 0, /*instruction_is_frsp*/
3542 0, /*instruction_is_convert_to_64bit*/
3543 0, /*instruction_is_convert_to_32bit*/
3544 1); /*single-precision*/
3545 }
3546 else {
3547 /*HACK!*/
3548 float s = *(double*)frA - *(double*)frB;
3549 *(double*)frT = s;
3550 }
3551 FPSCR_END(Rc);
45525d8d 3552 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
c143ef62
MM
3553
35540.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
54e98699
MM
3555*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3556*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3557*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3558*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3559 FPSCR_BEGIN;
3560 if (is_invalid_operation(processor, cia,
3561 *frA, *frC,
3562 fpscr_vxsnan | fpscr_vximz,
3563 0, /*single?*/
3564 0) /*negate?*/) {
3565 invalid_arithemetic_operation(processor, cia,
3566 frT, *frA, 0, *frC,
3567 0, /*instruction_is_frsp*/
3568 0, /*instruction_is_convert_to_64bit*/
3569 0, /*instruction_is_convert_to_32bit*/
3570 0); /*single-precision*/
3571 }
3572 else {
3573 /*HACK!*/
3574 double s = *(double*)frA * *(double*)frC;
3575 *(double*)frT = s;
3576 }
3577 FPSCR_END(Rc);
45525d8d 3578 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3579
c143ef62 35800.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
54e98699
MM
3581*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3582*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3583*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3584*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3585 FPSCR_BEGIN;
3586 if (is_invalid_operation(processor, cia,
3587 *frA, *frC,
3588 fpscr_vxsnan | fpscr_vximz,
3589 1, /*single?*/
3590 0) /*negate?*/) {
3591 invalid_arithemetic_operation(processor, cia,
3592 frT, *frA, 0, *frC,
3593 0, /*instruction_is_frsp*/
3594 0, /*instruction_is_convert_to_64bit*/
3595 0, /*instruction_is_convert_to_32bit*/
3596 1); /*single-precision*/
3597 }
3598 else {
3599 /*HACK!*/
3600 float s = *(double*)frA * *(double*)frC;
3601 *(double*)frT = s;
3602 }
3603 FPSCR_END(Rc);
45525d8d 3604 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3605
36060.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
54e98699
MM
3607*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3608*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3609*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3610*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
c143ef62
MM
3611 FPSCR_BEGIN;
3612 if (is_invalid_operation(processor, cia,
3613 *frA, *frB,
3614 fpscr_vxsnan | fpscr_vxzdz,
3615 0, /*single?*/
3616 0) /*negate?*/) {
3617 invalid_arithemetic_operation(processor, cia,
3618 frT, *frA, *frB, 0,
3619 0, /*instruction_is_frsp*/
3620 0, /*instruction_is_convert_to_64bit*/
3621 0, /*instruction_is_convert_to_32bit*/
3622 0); /*single-precision*/
3623 }
3624 else {
3625 /*HACK!*/
3626 double s = *(double*)frA / *(double*)frB;
3627 *(double*)frT = s;
3628 }
3629 FPSCR_END(Rc);
45525d8d 3630 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
845ff5a4 3631
c143ef62 36320.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
54e98699
MM
3633*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3634*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3635*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3636*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
c143ef62
MM
3637 FPSCR_BEGIN;
3638 if (is_invalid_operation(processor, cia,
3639 *frA, *frB,
3640 fpscr_vxsnan | fpscr_vxzdz,
3641 1, /*single?*/
3642 0) /*negate?*/) {
3643 invalid_arithemetic_operation(processor, cia,
3644 frT, *frA, *frB, 0,
3645 0, /*instruction_is_frsp*/
3646 0, /*instruction_is_convert_to_64bit*/
3647 0, /*instruction_is_convert_to_32bit*/
3648 1); /*single-precision*/
3649 }
3650 else {
3651 /*HACK!*/
3652 float s = *(double*)frA / *(double*)frB;
3653 *(double*)frT = s;
3654 }
3655 FPSCR_END(Rc);
45525d8d 3656 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
c143ef62
MM
3657
36580.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
54e98699
MM
3659*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3660*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3661*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3662*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3663 FPSCR_BEGIN;
3664 double product; /*HACK! - incorrectly loosing precision ... */
3665 /* compute the multiply */
3666 if (is_invalid_operation(processor, cia,
3667 *frA, *frC,
3668 fpscr_vxsnan | fpscr_vximz,
3669 0, /*single?*/
3670 0) /*negate?*/) {
3671 invalid_arithemetic_operation(processor, cia,
3672 (unsigned64*)&product, *frA, 0, *frC,
3673 0, /*instruction_is_frsp*/
3674 0, /*instruction_is_convert_to_64bit*/
3675 0, /*instruction_is_convert_to_32bit*/
3676 0); /*single-precision*/
3677 }
3678 else {
3679 /*HACK!*/
3680 product = *(double*)frA * *(double*)frC;
3681 }
3682 /* compute the add */
3683 if (is_invalid_operation(processor, cia,
3684 product, *frB,
3685 fpscr_vxsnan | fpscr_vxisi,
3686 0, /*single?*/
3687 0) /*negate?*/) {
3688 invalid_arithemetic_operation(processor, cia,
3689 frT, product, *frB, 0,
3690 0, /*instruction_is_frsp*/
3691 0, /*instruction_is_convert_to_64bit*/
3692 0, /*instruction_is_convert_to_32bit*/
3693 0); /*single-precision*/
3694 }
3695 else {
3696 /*HACK!*/
3697 double s = product + *(double*)frB;
3698 *(double*)frT = s;
3699 }
3700 FPSCR_END(Rc);
45525d8d 3701 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3702
c143ef62 37030.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
54e98699
MM
3704*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3705*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3706*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3707*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3708 FPSCR_BEGIN;
3709 float product; /*HACK! - incorrectly loosing precision ... */
3710 /* compute the multiply */
3711 if (is_invalid_operation(processor, cia,
3712 *frA, *frC,
3713 fpscr_vxsnan | fpscr_vximz,
3714 1, /*single?*/
3715 0) /*negate?*/) {
3716 invalid_arithemetic_operation(processor, cia,
3717 (unsigned64*)&product, *frA, 0, *frC,
3718 0, /*instruction_is_frsp*/
3719 0, /*instruction_is_convert_to_64bit*/
3720 0, /*instruction_is_convert_to_32bit*/
3721 0); /*single-precision*/
3722 }
3723 else {
3724 /*HACK!*/
3725 product = *(double*)frA * *(double*)frC;
3726 }
3727 /* compute the add */
3728 if (is_invalid_operation(processor, cia,
3729 product, *frB,
3730 fpscr_vxsnan | fpscr_vxisi,
3731 1, /*single?*/
3732 0) /*negate?*/) {
3733 invalid_arithemetic_operation(processor, cia,
3734 frT, product, *frB, 0,
3735 0, /*instruction_is_frsp*/
3736 0, /*instruction_is_convert_to_64bit*/
3737 0, /*instruction_is_convert_to_32bit*/
3738 0); /*single-precision*/
3739 }
3740 else {
3741 /*HACK!*/
3742 float s = product + *(double*)frB;
3743 *(double*)frT = (double)s;
3744 }
3745 FPSCR_END(Rc);
45525d8d 3746 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4a0351ab
MM
3747
37480.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3749*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3750*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3751*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
54e98699 3752*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3753 FPSCR_BEGIN;
3754 double product; /*HACK! - incorrectly loosing precision ... */
3755 /* compute the multiply */
3756 if (is_invalid_operation(processor, cia,
3757 *frA, *frC,
3758 fpscr_vxsnan | fpscr_vximz,
3759 0, /*single?*/
3760 0) /*negate?*/) {
3761 invalid_arithemetic_operation(processor, cia,
3762 (unsigned64*)&product, *frA, 0, *frC,
3763 0, /*instruction_is_frsp*/
3764 0, /*instruction_is_convert_to_64bit*/
3765 0, /*instruction_is_convert_to_32bit*/
3766 0); /*single-precision*/
3767 }
3768 else {
3769 /*HACK!*/
3770 product = *(double*)frA * *(double*)frC;
3771 }
3772 /* compute the subtract */
3773 if (is_invalid_operation(processor, cia,
3774 product, *frB,
3775 fpscr_vxsnan | fpscr_vxisi,
3776 0, /*single?*/
3777 0) /*negate?*/) {
3778 invalid_arithemetic_operation(processor, cia,
3779 frT, product, *frB, 0,
3780 0, /*instruction_is_frsp*/
3781 0, /*instruction_is_convert_to_64bit*/
3782 0, /*instruction_is_convert_to_32bit*/
3783 0); /*single-precision*/
3784 }
3785 else {
3786 /*HACK!*/
3787 double s = product - *(double*)frB;
3788 *(double*)frT = s;
3789 }
3790 FPSCR_END(Rc);
45525d8d 3791 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3792
c143ef62 37930.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
54e98699
MM
3794*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3795*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3796*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3797*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3798 FPSCR_BEGIN;
3799 float product; /*HACK! - incorrectly loosing precision ... */
3800 /* compute the multiply */
3801 if (is_invalid_operation(processor, cia,
3802 *frA, *frC,
3803 fpscr_vxsnan | fpscr_vximz,
3804 1, /*single?*/
3805 0) /*negate?*/) {
3806 invalid_arithemetic_operation(processor, cia,
3807 (unsigned64*)&product, *frA, 0, *frC,
3808 0, /*instruction_is_frsp*/
3809 0, /*instruction_is_convert_to_64bit*/
3810 0, /*instruction_is_convert_to_32bit*/
3811 0); /*single-precision*/
3812 }
3813 else {
3814 /*HACK!*/
3815 product = *(double*)frA * *(double*)frC;
3816 }
3817 /* compute the subtract */
3818 if (is_invalid_operation(processor, cia,
3819 product, *frB,
3820 fpscr_vxsnan | fpscr_vxisi,
3821 1, /*single?*/
3822 0) /*negate?*/) {
3823 invalid_arithemetic_operation(processor, cia,
3824 frT, product, *frB, 0,
3825 0, /*instruction_is_frsp*/
3826 0, /*instruction_is_convert_to_64bit*/
3827 0, /*instruction_is_convert_to_32bit*/
3828 0); /*single-precision*/
3829 }
3830 else {
3831 /*HACK!*/
3832 float s = product - *(double*)frB;
3833 *(double*)frT = (double)s;
3834 }
3835 FPSCR_END(Rc);
45525d8d 3836 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3837
38380.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
54e98699
MM
3839*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3840*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3841*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3842*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3843 FPSCR_BEGIN;
3844 double product; /*HACK! - incorrectly loosing precision ... */
3845 /* compute the multiply */
3846 if (is_invalid_operation(processor, cia,
3847 *frA, *frC,
3848 fpscr_vxsnan | fpscr_vximz,
3849 0, /*single?*/
3850 0) /*negate?*/) {
3851 invalid_arithemetic_operation(processor, cia,
3852 (unsigned64*)&product, *frA, 0, *frC,
3853 0, /*instruction_is_frsp*/
3854 0, /*instruction_is_convert_to_64bit*/
3855 0, /*instruction_is_convert_to_32bit*/
3856 0); /*single-precision*/
3857 }
3858 else {
3859 /*HACK!*/
3860 product = *(double*)frA * *(double*)frC;
3861 }
3862 /* compute the add */
3863 if (is_invalid_operation(processor, cia,
3864 product, *frB,
3865 fpscr_vxsnan | fpscr_vxisi,
3866 0, /*single?*/
3867 0) /*negate?*/) {
3868 invalid_arithemetic_operation(processor, cia,
3869 frT, product, *frB, 0,
3870 0, /*instruction_is_frsp*/
3871 0, /*instruction_is_convert_to_64bit*/
3872 0, /*instruction_is_convert_to_32bit*/
3873 0); /*single-precision*/
3874 }
3875 else {
3876 /*HACK!*/
3877 double s = -(product + *(double*)frB);
3878 *(double*)frT = s;
3879 }
3880 FPSCR_END(Rc);
45525d8d 3881 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3882
c143ef62 38830.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
54e98699
MM
3884*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3885*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3886*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3887*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3888 FPSCR_BEGIN;
3889 float product; /*HACK! - incorrectly loosing precision ... */
3890 /* compute the multiply */
3891 if (is_invalid_operation(processor, cia,
3892 *frA, *frC,
3893 fpscr_vxsnan | fpscr_vximz,
3894 1, /*single?*/
3895 0) /*negate?*/) {
3896 invalid_arithemetic_operation(processor, cia,
3897 (unsigned64*)&product, *frA, 0, *frC,
3898 0, /*instruction_is_frsp*/
3899 0, /*instruction_is_convert_to_64bit*/
3900 0, /*instruction_is_convert_to_32bit*/
3901 0); /*single-precision*/
3902 }
3903 else {
3904 /*HACK!*/
3905 product = *(double*)frA * *(double*)frC;
3906 }
3907 /* compute the add */
3908 if (is_invalid_operation(processor, cia,
3909 product, *frB,
3910 fpscr_vxsnan | fpscr_vxisi,
3911 1, /*single?*/
3912 0) /*negate?*/) {
3913 invalid_arithemetic_operation(processor, cia,
3914 frT, product, *frB, 0,
3915 0, /*instruction_is_frsp*/
3916 0, /*instruction_is_convert_to_64bit*/
3917 0, /*instruction_is_convert_to_32bit*/
3918 0); /*single-precision*/
3919 }
3920 else {
3921 /*HACK!*/
3922 float s = -(product + *(double*)frB);
3923 *(double*)frT = (double)s;
3924 }
3925 FPSCR_END(Rc);
45525d8d 3926 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3927
39280.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
54e98699
MM
3929*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3930*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3931*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3932*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3933 FPSCR_BEGIN;
3934 double product; /*HACK! - incorrectly loosing precision ... */
3935 /* compute the multiply */
3936 if (is_invalid_operation(processor, cia,
3937 *frA, *frC,
3938 fpscr_vxsnan | fpscr_vximz,
3939 0, /*single?*/
3940 0) /*negate?*/) {
3941 invalid_arithemetic_operation(processor, cia,
3942 (unsigned64*)&product, *frA, 0, *frC,
3943 0, /*instruction_is_frsp*/
3944 0, /*instruction_is_convert_to_64bit*/
3945 0, /*instruction_is_convert_to_32bit*/
3946 0); /*single-precision*/
3947 }
3948 else {
3949 /*HACK!*/
3950 product = *(double*)frA * *(double*)frC;
3951 }
3952 /* compute the subtract */
3953 if (is_invalid_operation(processor, cia,
3954 product, *frB,
3955 fpscr_vxsnan | fpscr_vxisi,
3956 0, /*single?*/
3957 0) /*negate?*/) {
3958 invalid_arithemetic_operation(processor, cia,
3959 frT, product, *frB, 0,
3960 0, /*instruction_is_frsp*/
3961 0, /*instruction_is_convert_to_64bit*/
3962 0, /*instruction_is_convert_to_32bit*/
3963 0); /*single-precision*/
3964 }
3965 else {
3966 /*HACK!*/
3967 double s = -(product - *(double*)frB);
3968 *(double*)frT = s;
3969 }
3970 FPSCR_END(Rc);
45525d8d 3971 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3972
c143ef62 39730.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
54e98699
MM
3974*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3975*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3976*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3977*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3978 FPSCR_BEGIN;
3979 float product; /*HACK! - incorrectly loosing precision ... */
3980 /* compute the multiply */
3981 if (is_invalid_operation(processor, cia,
3982 *frA, *frC,
3983 fpscr_vxsnan | fpscr_vximz,
3984 1, /*single?*/
3985 0) /*negate?*/) {
3986 invalid_arithemetic_operation(processor, cia,
3987 (unsigned64*)&product, *frA, 0, *frC,
3988 0, /*instruction_is_frsp*/
3989 0, /*instruction_is_convert_to_64bit*/
3990 0, /*instruction_is_convert_to_32bit*/
3991 0); /*single-precision*/
3992 }
3993 else {
3994 /*HACK!*/
3995 product = *(double*)frA * *(double*)frC;
3996 }
3997 /* compute the subtract */
3998 if (is_invalid_operation(processor, cia,
3999 product, *frB,
4000 fpscr_vxsnan | fpscr_vxisi,
4001 1, /*single?*/
4002 0) /*negate?*/) {
4003 invalid_arithemetic_operation(processor, cia,
4004 frT, product, *frB, 0,
4005 0, /*instruction_is_frsp*/
4006 0, /*instruction_is_convert_to_64bit*/
4007 0, /*instruction_is_convert_to_32bit*/
4008 0); /*single-precision*/
4009 }
4010 else {
4011 /*HACK!*/
4012 float s = -(product - *(double*)frB);
4013 *(double*)frT = (double)s;
4014 }
4015 FPSCR_END(Rc);
45525d8d 4016 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
4017
4018
4019#
4020# I.4.6.6 Floating-Point Rounding and Conversion Instructions
4021#
4022
40230.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
54e98699
MM
4024*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4025*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4026*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4027*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4028 int sign;
4029 int exp;
4030 unsigned64 frac_grx;
4031 /* split off cases for what to do */
4032 if (EXTRACTED64(*frB, 1, 11) < 897
4033 && EXTRACTED64(*frB, 1, 63) > 0) {
4034 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
4035 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
4036 }
4037 if (EXTRACTED64(*frB, 1, 11) > 1150
4038 && EXTRACTED64(*frB, 1, 11) < 2047) {
4039 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4040 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
4041 }
4042 if (EXTRACTED64(*frB, 1, 11) > 896
4043 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
4044 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
4045 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4046 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
4047 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
4048 if (EXTRACTED64(*frB, 12, 12) == 0
4049 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
4050 }
4051 /* handle them */
4052 Disabled_Exponent_Underflow:
4053 sign = EXTRACTED64(*frB, 0, 0);
4054 if (EXTRACTED64(*frB, 1, 11) == 0) {
4055 exp = -1022;
4056 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4057 }
4058 if (EXTRACTED64(*frB, 1, 11) > 0) {
4059 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4060 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4061 }
c143ef62
MM
4062 /* G|R|X == zero from above */
4063 while (exp < -126) {
4064 exp = exp - 1;
4065 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4066 | MASKED64(frac_grx, 55, 55));
4067 }
4068 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4069 Round_Single(processor, sign, &exp, &frac_grx);
4070 FPSCR_SET_XX(FPSCR & fpscr_fi);
4071 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4072 *frT = INSERTED64(sign, 0, 0);
4073 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4074 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4075 }
4076 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4077 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4078 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4079 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4080 }
4081 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4082 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4083 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4084 }
4085 /*Normalize_Operand:*/
4086 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4087 exp = exp - 1;
4088 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4089 }
4090 *frT = (INSERTED64(sign, 0, 0)
4091 | INSERTED64(exp + 1023, 1, 11)
4092 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4093 }
4094 goto Done;
4095 Enabled_Exponent_Underflow:
4096 FPSCR_SET_UX(1);
4097 sign = EXTRACTED64(*frB, 0, 0);
4098 if (EXTRACTED64(*frB, 1, 11) == 0) {
4099 exp = -1022;
4100 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4101 }
4102 if (EXTRACTED64(*frB, 1, 11) > 0) {
4103 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4104 frac_grx = (BIT64(0) |
4105 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4106 }
4107 /*Normalize_Operand:*/
4108 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4109 exp = exp - 1;
4110 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4111 }
4112 Round_Single(processor, sign, &exp, &frac_grx);
4113 FPSCR_SET_XX(FPSCR & fpscr_fi);
4114 exp = exp + 192;
4115 *frT = (INSERTED64(sign, 0, 0)
4116 | INSERTED64(exp + 1023, 1, 11)
4117 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4118 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4119 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4120 goto Done;
4121 Disabled_Exponent_Overflow:
4122 FPSCR_SET_OX(1);
4123 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4124 if (EXTRACTED64(*frB, 0, 0) == 0) {
4125 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4126 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4127 }
4128 if (EXTRACTED64(*frB, 0, 0) == 1) {
4129 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4130 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4131 }
4132 }
4133 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4134 if (EXTRACTED64(*frB, 0, 0) == 0) {
4135 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4136 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4137 }
4138 if (EXTRACTED64(*frB, 0, 0) == 1) {
4139 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4140 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4141 }
4142 }
4143 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4144 if (EXTRACTED64(*frB, 0, 0) == 0) {
4145 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4146 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4147 }
4148 if (EXTRACTED64(*frB, 0, 0) == 1) {
4149 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4150 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4151 }
4152 }
4153 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4154 if (EXTRACTED64(*frB, 0, 0) == 0) {
4155 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4156 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4157 }
4158 if (EXTRACTED64(*frB, 0, 0) == 1) {
4159 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4160 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4161 }
4162 }
4163 /* FPSCR[FR] <- undefined */
4164 FPSCR_SET_FI(1);
4165 FPSCR_SET_XX(1);
4166 goto Done;
4167 Enabled_Exponent_Overflow:
4168 sign = EXTRACTED64(*frB, 0, 0);
4169 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4170 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4171 Round_Single(processor, sign, &exp, &frac_grx);
4172 FPSCR_SET_XX(FPSCR & fpscr_fi);
4173 Enabled_Overflow:
4174 FPSCR_SET_OX(1);
4175 exp = exp - 192;
4176 *frT = (INSERTED64(sign, 0, 0)
4177 | INSERTED64(exp + 1023, 1, 11)
4178 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4179 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4180 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4181 goto Done;
4182 Zero_Operand:
4183 *frT = *frB;
4184 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4185 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4186 FPSCR_SET_FR(0);
4187 FPSCR_SET_FI(0);
4188 goto Done;
4189 Infinity_Operand:
4190 *frT = *frB;
4191 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4192 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4193 FPSCR_SET_FR(0);
4194 FPSCR_SET_FI(0);
4195 goto Done;
4196 QNaN_Operand:
4197 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4198 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4199 FPSCR_SET_FR(0);
4200 FPSCR_SET_FI(0);
4201 goto Done;
4202 SNaN_Operand:
4203 FPSCR_OR_VX(fpscr_vxsnan);
4204 if ((FPSCR & fpscr_ve) == 0) {
4205 *frT = (MASKED64(*frB, 0, 11)
4206 | BIT64(12)
4207 | MASKED64(*frB, 13, 34));
4208 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4209 }
4210 FPSCR_SET_FR(0);
4211 FPSCR_SET_FI(0);
4212 goto Done;
4213 Normal_Operand:
4214 sign = EXTRACTED64(*frB, 0, 0);
4215 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4216 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4217 Round_Single(processor, sign, &exp, &frac_grx);
4218 FPSCR_SET_XX(FPSCR & fpscr_fi);
4219 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4220 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4221 *frT = (INSERTED64(sign, 0, 0)
4222 | INSERTED64(exp + 1023, 1, 11)
4223 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4224 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4225 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4226 goto Done;
4227 Done:
45525d8d 4228 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 4229
c143ef62 42300.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
845ff5a4 4231
c143ef62 42320.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
845ff5a4 4233
c143ef62 42340.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
845ff5a4 4235
c143ef62 42360.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
54e98699
MM
4237*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4238*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4239*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4240*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4241 FPSCR_BEGIN;
4242 convert_to_integer(processor, cia,
4243 frT, *frB,
4244 fpscr_rn_round_towards_zero, 32);
4245 FPSCR_END(Rc);
45525d8d 4246 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 4247
c143ef62
MM
42480.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4249 int sign = EXTRACTED64(*frB, 0, 0);
4250 int exp = 63;
4251 unsigned64 frac = *frB;
4252 if (frac == 0) goto Zero_Operand;
4253 if (sign == 1) frac = ~frac + 1;
4254 while (EXTRACTED64(frac, 0, 0) == 0) {
4255 /*??? do the loop 0 times if (FRB) = max negative integer */
4256 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4257 exp = exp - 1;
4258 }
4259 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4260 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4261 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4262 *frT = (INSERTED64(sign, 0, 0)
4263 | INSERTED64(exp + 1023, 1, 11)
4264 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4265 goto Done;
4266 /**/
4267 Zero_Operand:
4268 FPSCR_SET_FR(0);
4269 FPSCR_SET_FI(0);
4270 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4271 *frT = 0;
4272 goto Done;
4273 /**/
4274 Done:
45525d8d 4275 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
c143ef62
MM
4276
4277#
4278# I.4.6.7 Floating-Point Compare Instructions
4279#
4280
42810.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
54e98699
MM
4282*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4283*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4284*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4285*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4286 FPSCR_BEGIN;
4287 unsigned c;
4288 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4289 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4290 else if (is_less_than(frA, frB))
4291 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4292 else if (is_greater_than(frA, frB))
4293 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4294 else
4295 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4296 FPSCR_SET_FPCC(c);
4297 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4298 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4299 FPSCR_OR_VX(fpscr_vxsnan);
4300 FPSCR_END(0);
45525d8d 4301 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
845ff5a4 4302
c143ef62 43030.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
54e98699
MM
4304*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4305*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4306*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4307*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4308 FPSCR_BEGIN;
4309 unsigned c;
4310 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4311 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4312 else if (is_less_than(frA, frB))
4313 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4314 else if (is_greater_than(frA, frB))
4315 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4316 else
4317 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4318 FPSCR_SET_FPCC(c);
4319 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4320 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4321 FPSCR_OR_VX(fpscr_vxsnan);
4322 if ((FPSCR & fpscr_ve) == 0)
4323 FPSCR_OR_VX(fpscr_vxvc);
4324 }
4325 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4326 FPSCR_OR_VX(fpscr_vxvc);
4327 }
4328 FPSCR_END(0);
45525d8d 4329 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
c143ef62
MM
4330
4331
4332#
4333# I.4.6.8 Floating-Point Status and Control Register Instructions
4334#
4335
43360.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
845ff5a4 4337
c143ef62 43380.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
845ff5a4 4339
c143ef62 43400.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
845ff5a4 4341
c143ef62 43420.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
845ff5a4 4343
c143ef62 43440.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
845ff5a4 4345
c143ef62
MM
43460.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4347
4348
4349#
4350# I.A.1.1 Floating-Point Store Instruction
4351#
43520.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4353
4354#
4355# I.A.1.2 Floating-Point Arithmetic Instructions
4356#
4357
43580.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
845ff5a4 4359
c143ef62
MM
43600.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4361
43620.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
845ff5a4 4363
c143ef62
MM
43640.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4365
4366#
4367# I.A.1.3 Floating-Point Select Instruction
4368#
4369
43700.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4371
4372
4373#
4374# II.3.2 Cache Management Instructions
4375#
4376
43770.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
54e98699
MM
4378*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4379*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4380*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4381*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
80948f39
MM
4382 /* blindly flush all instruction cache entries */
4383 #if WITH_IDECODE_CACHE_SIZE
4384 cpu_flush_icache(processor);
4385 #endif
45525d8d 4386 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
4387
43880.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
54e98699
MM
4389*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4390*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4391*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4392*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
c143ef62 4393 cpu_synchronize_context(processor);
45525d8d 4394 PPC_INSN_INT(0, 0, 0);
c143ef62
MM
4395
4396
4397#
4398# II.3.2.2 Data Cache Instructions
4399#
4400
44010.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
54e98699
MM
4402*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4403*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4404*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4405*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
845ff5a4 4406 TRACE(trace_tbd,("Data Cache Block Touch\n"));
45525d8d 4407 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
056e975c 4408
c143ef62 44090.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
54e98699
MM
4410*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4411*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4412*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4413*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
845ff5a4 4414 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
45525d8d 4415 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
056e975c 4416
c143ef62 44170.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
54e98699
MM
4418*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4419*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4420*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4421*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
845ff5a4 4422 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
45525d8d 4423 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
056e975c 4424
c143ef62 44250.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
54e98699
MM
4426*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4427*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4428*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4429*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
845ff5a4 4430 TRACE(trace_tbd,("Data Cache Block Store\n"));
45525d8d 4431 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
056e975c 4432
c143ef62 44330.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
54e98699
MM
4434*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4435*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4436*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4437*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
845ff5a4 4438 TRACE(trace_tbd,("Data Cache Block Flush\n"));
45525d8d 4439 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
c143ef62
MM
4440
4441#
845ff5a4 4442# II.3.3 Enforce In-order Execution of I/O Instruction
c143ef62
MM
4443#
4444
44450.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4446 /* Since this model has no instruction overlap
4447 this instruction need do nothing */
4448
4449#
4450# II.4.1 Time Base Instructions
4451#
4452
44530.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
54e98699
MM
4454*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4455*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4456*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62
MM
4457 int n = (tbr{5:9} << 5) | tbr{0:4};
4458 if (n == 268) {
4459 if (is_64bit_implementation) *rT = TB;
4460 else *rT = EXTRACTED64(TB, 32, 63);
4461 }
4462 else if (n == 269) {
4463 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4464 else *rT = EXTRACTED64(TB, 0, 31);
4465 }
4466 else
4467 program_interrupt(processor, cia,
4468 illegal_instruction_program_interrupt);
4469
4470
4471#
4472# III.2.3.1 System Linkage Instructions
4473#
4474
80948f39 44750.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
54e98699
MM
4476*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4477*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4478*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4479*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
80948f39
MM
4480 if (IS_PROBLEM_STATE(processor)) {
4481 program_interrupt(processor, cia,
4482 privileged_instruction_program_interrupt);
4483 }
4484 else {
4485 MSR = (MASKED(SRR1, 0, 32)
4486 | MASKED(SRR1, 37, 41)
4487 | MASKED(SRR1, 48, 63));
4488 NIA = MASKED(SRR0, 0, 61);
4489 cpu_synchronize_context(processor);
4490 }
c143ef62
MM
4491
4492#
4493# III.3.4.1 Move to/from System Register Instructions
4494#
4495
f2181eff
MM
4496#0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4497#0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
c143ef62 44980.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
54e98699
MM
4499*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4500*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4501*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4502*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4503 if (IS_PROBLEM_STATE(processor))
4504 program_interrupt(processor, cia,
4505 privileged_instruction_program_interrupt);
4506 else
4507 MSR = *rS;
845ff5a4 4508
c143ef62 45090.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
54e98699
MM
4510*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4511*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4512*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4513*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62
MM
4514 if (IS_PROBLEM_STATE(processor))
4515 program_interrupt(processor, cia,
4516 privileged_instruction_program_interrupt);
4517 else
4518 *rT = MSR;
4519
4520
4521#
4522# III.4.11.1 Cache Management Instructions
4523#
4524
45250.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
54e98699
MM
4526*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4527*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4528*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4529*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
845ff5a4
MM
4530 if (IS_PROBLEM_STATE(processor))
4531 program_interrupt(processor, cia,
4532 privileged_instruction_program_interrupt);
4533 else
4534 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
c143ef62
MM
4535
4536#
4537# III.4.11.2 Segment Register Manipulation Instructions
4538#
4539
45400.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
54e98699
MM
4541*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4542*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4543*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4544*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4545 if (IS_PROBLEM_STATE(processor))
4546 program_interrupt(processor, cia,
4547 privileged_instruction_program_interrupt);
4548 else
4549 SEGREG(SR) = *rS;
845ff5a4 4550
c143ef62 45510.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
54e98699
MM
4552*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4553*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4554*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4555*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4556 if (IS_PROBLEM_STATE(processor))
4557 program_interrupt(processor, cia,
4558 privileged_instruction_program_interrupt);
4559 else
4560 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
845ff5a4 4561
c143ef62 45620.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
54e98699
MM
4563*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4564*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4565*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4566*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4567 if (IS_PROBLEM_STATE(processor))
4568 program_interrupt(processor, cia,
4569 privileged_instruction_program_interrupt);
4570 else
4571 *rT = SEGREG(SR);
845ff5a4 4572
c143ef62 45730.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
54e98699
MM
4574*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4575*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4576*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4577*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4578 if (IS_PROBLEM_STATE(processor))
4579 program_interrupt(processor, cia,
4580 privileged_instruction_program_interrupt);
4581 else
4582 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4583
4584
4585#
4586# III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4587#
4588
45890.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
845ff5a4 4590
c143ef62
MM
45910.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4592
45930.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
845ff5a4 4594
c143ef62
MM
45950.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4596
45970.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4598
4599
4600#
4601# III.A.1.2 External Access Instructions
4602#
4603
46040.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
845ff5a4 4605
c143ef62 46060.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
This page took 0.281808 seconds and 4 git commands to generate.