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