]> Git Repo - binutils.git/blame - sim/ppc/ppc-instructions
Make WITH_MODEL_ISSUE==0 not core dump
[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;
3d2f9d7c
MM
1360 if (WITH_MODEL_ISSUE)
1361 model_branches(cpu_model(processor), 1, -1);
84bbbc35 1362
c143ef62 13630.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
54e98699
MM
1364*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1365*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1366*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1367*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
84bbbc35 1368 int M, ctr_ok, cond_ok, succeed;
3d2f9d7c 1369 if (WITH_MODEL_ISSUE && ! BO{0})
54e98699 1370 model_wait_for_cr(cpu_model(processor), BIT32_BI);
c143ef62
MM
1371 if (is_64bit_implementation && is_64bit_mode) M = 0;
1372 else M = 32;
1373 if (!BO{2}) CTR = CTR - 1;
1374 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1375 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
84bbbc35 1376 if (ctr_ok && cond_ok) {
c143ef62
MM
1377 if (AA) NIA = IEA(EXTS(BD_0b00));
1378 else NIA = IEA(CIA + EXTS(BD_0b00));
84bbbc35
MM
1379 succeed = 1;
1380 }
1381 else
1382 succeed = 0;
c143ef62 1383 if (LK) LR = (spreg)IEA(CIA + 4);
3d2f9d7c
MM
1384 if (WITH_MODEL_ISSUE)
1385 model_branches(cpu_model(processor), succeed, BO);
84bbbc35
MM
1386 if (! BO{0}) {
1387 int reverse;
1388 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1389 reverse = EXTS(BD_0b00) < 0;
1390 } else { /* branch prediction bit not set */
1391 reverse = EXTS(BD_0b00) >= 0;
1392 }
3d2f9d7c
MM
1393 if (WITH_MODEL_ISSUE)
1394 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
84bbbc35
MM
1395 }
1396
c143ef62 13970.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
54e98699
MM
1398*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1399*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1400*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1401*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
84bbbc35 1402 int M, ctr_ok, cond_ok, succeed;
c143ef62
MM
1403 if (is_64bit_implementation && is_64bit_mode) M = 0;
1404 else M = 32;
3d2f9d7c 1405 if (WITH_MODEL_ISSUE && ! BO{0})
54e98699 1406 model_wait_for_cr(cpu_model(processor), BIT32_BI);
c143ef62
MM
1407 if (!BO{2}) CTR = CTR - 1;
1408 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1409 cond_ok = BO{0} || (CR{BI} == BO{1});
84bbbc35
MM
1410 if (ctr_ok && cond_ok) {
1411 NIA = IEA(LR_0b00);
1412 succeed = 1;
1413 }
1414 else
1415 succeed = 0;
c143ef62 1416 if (LK) LR = (spreg)IEA(CIA + 4);
3d2f9d7c
MM
1417 if (WITH_MODEL_ISSUE) {
1418 model_branches(cpu_model(processor), succeed, BO);
1419 if (! BO{0})
1420 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1421 }
84bbbc35 1422
c143ef62 14230.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
54e98699
MM
1424*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1425*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1426*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1427*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
84bbbc35 1428 int cond_ok, succeed;
3d2f9d7c 1429 if (WITH_MODEL_ISSUE && ! BO{0})
54e98699 1430 model_wait_for_cr(cpu_model(processor), BIT32_BI);
c143ef62 1431 cond_ok = BO{0} || (CR{BI} == BO{1});
84bbbc35
MM
1432 if (cond_ok) {
1433 NIA = IEA(CTR_0b00);
1434 succeed = 1;
1435 }
1436 else
1437 succeed = 0;
c143ef62 1438 if (LK) LR = (spreg)IEA(CIA + 4);
3d2f9d7c
MM
1439 if (WITH_MODEL_ISSUE) {
1440 model_branches(cpu_model(processor), succeed, BO);
1441 if (! BO{0})
1442 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1443 }
c143ef62
MM
1444
1445#
1446# I.2.4.2 System Call Instruction
1447#
14480.17,6./,11./,16./,30.1,31./:SC:t::System Call
54e98699
MM
1449*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1450*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1451*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1452*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
3d2f9d7c
MM
1453 if (WITH_MODEL_ISSUE)
1454 model_serialize(my_index, cpu_model(processor));
c143ef62
MM
1455 system_call_interrupt(processor, cia);
1456
1457#
1458# I.2.4.3 Condition Register Logical Instructions
1459#
14600.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
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.449,31./:XL::cror:Condition Register OR
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.193,31./:XL::crxor:Condition Register XOR
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.225,31./:XL::crnand:Condition Register NAND
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.33,31./:XL::crnor:Condition Register NOR
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.289,31./:XL::creqv:Condition Register Equivalent
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.129,31./:XL::crandc:Condition Register AND 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);
845ff5a4 1515
c143ef62 15160.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
54e98699
MM
1517*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1518*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1519*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1520*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1521 BLIT32(CR, BT, CR{BA} || !CR{BB});
f2181eff 1522 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
c143ef62
MM
1523
1524#
1525# I.2.4.4 Condition Register Field Instruction
1526#
15270.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
54e98699
MM
1528*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1529*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1530*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1531*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1532 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
f2181eff 1533 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
c143ef62
MM
1534
1535
1536#
1537# I.3.3.2 Fixed-Point Load Instructions
1538#
1539
15400.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
54e98699
MM
1541*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1542*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1543*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1544*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1545 unsigned_word b;
1546 unsigned_word EA;
1547 if (RA == 0) b = 0;
1548 else b = *rA;
1549 EA = b + EXTS(D);
1550 *rT = MEM(unsigned, EA, 1);
45525d8d 1551 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
54e98699 1552
845ff5a4 1553
c143ef62 15540.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
54e98699
MM
1555*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1556*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1557*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1558*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1559 unsigned_word b;
1560 unsigned_word EA;
1561 if (RA == 0) b = 0;
1562 else b = *rA;
1563 EA = b + *rB;
1564 *rT = MEM(unsigned, EA, 1);
45525d8d 1565 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 1566
c143ef62 15670.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
54e98699
MM
1568*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1569*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1570*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1571*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1572 unsigned_word EA;
1573 if (RA == 0 || RA == RT)
1574 program_interrupt(processor, cia,
1575 illegal_instruction_program_interrupt);
1576 EA = *rA + EXTS(D);
1577 *rT = MEM(unsigned, EA, 1);
1578 *rA = EA;
45525d8d 1579 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1580
c143ef62 15810.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
54e98699
MM
1582*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1583*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1584*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1585*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1586 unsigned_word EA;
1587 if (RA == 0 || RA == RT)
1588 program_interrupt(processor, cia,
1589 illegal_instruction_program_interrupt);
1590 EA = *rA + *rB;
1591 *rT = MEM(unsigned, EA, 1);
1592 *rA = EA;
45525d8d 1593 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1594
15950.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
54e98699
MM
1596*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1597*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1598*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1599*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1600 unsigned_word b;
1601 unsigned_word EA;
1602 if (RA == 0) b = 0;
1603 else b = *rA;
1604 EA = b + EXTS(D);
1605 *rT = MEM(unsigned, EA, 2);
45525d8d 1606 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 1607
c143ef62 16080.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
54e98699
MM
1609*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1610*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1611*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1612*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1613 unsigned_word b;
1614 unsigned_word EA;
1615 if (RA == 0) b = 0;
1616 else b = *rA;
1617 EA = b + *rB;
1618 *rT = MEM(unsigned, EA, 2);
45525d8d 1619 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
54e98699 1620
c143ef62 16210.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
54e98699
MM
1622*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1623*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1624*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1625*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1626 unsigned_word EA;
1627 if (RA == 0 || RA == RT)
1628 program_interrupt(processor, cia,
1629 illegal_instruction_program_interrupt);
1630 EA = *rA + EXTS(D);
1631 *rT = MEM(unsigned, EA, 2);
1632 *rA = EA;
45525d8d 1633 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1634
c143ef62 16350.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
54e98699
MM
1636*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1637*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1638*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1639*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1640 unsigned_word EA;
1641 if (RA == 0 || RA == RT)
1642 program_interrupt(processor, cia,
1643 illegal_instruction_program_interrupt);
1644 EA = *rA + *rB;
1645 *rT = MEM(unsigned, EA, 2);
1646 *rA = EA;
45525d8d 1647 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1648
16490.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
54e98699
MM
1650*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1651*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1652*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1653*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1654 unsigned_word b;
1655 unsigned_word EA;
1656 if (RA == 0) b = 0;
1657 else b = *rA;
1658 EA = b + EXTS(D);
1659 *rT = MEM(signed, EA, 2);
45525d8d 1660 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 1661
c143ef62 16620.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
54e98699
MM
1663*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1664*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1665*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1666*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1667 unsigned_word b;
1668 unsigned_word EA;
1669 if (RA == 0) b = 0;
1670 else b = *rA;
1671 EA = b + *rB;
1672 *rT = MEM(signed, EA, 2);
45525d8d 1673 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 1674
c143ef62 16750.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
54e98699
MM
1676*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1677*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1678*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1679*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1680 unsigned_word EA;
1681 if (RA == 0 || RA == RT)
1682 program_interrupt(processor, cia,
1683 illegal_instruction_program_interrupt);
1684 EA = *rA + EXTS(D);
1685 *rT = MEM(signed, EA, 2);
45525d8d 1686 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1687
c143ef62 16880.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
54e98699
MM
1689*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1690*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1691*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1692*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1693 unsigned_word EA;
1694 if (RA == 0 || RA == RT)
1695 program_interrupt(processor, cia,
1696 illegal_instruction_program_interrupt);
1697 EA = *rA + *rB;
1698 *rT = MEM(signed, EA, 2);
1699 *rA = EA;
45525d8d 1700 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1701
17020.32,6.RT,11.RA,16.D:D:::Load Word and Zero
54e98699
MM
1703*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1704*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1705*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1706*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1707 unsigned_word b;
1708 unsigned_word EA;
1709 if (RA == 0) b = 0;
1710 else b = *rA;
1711 EA = b + EXTS(D);
1712 *rT = MEM(unsigned, EA, 4);
45525d8d 1713 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 1714
c143ef62 17150.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
54e98699
MM
1716*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1717*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1718*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1719*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1720 unsigned_word b;
1721 unsigned_word EA;
1722 if (RA == 0) b = 0;
1723 else b = *rA;
1724 EA = b + *rB;
1725 *rT = MEM(unsigned, EA, 4);
45525d8d 1726 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 1727
c143ef62 17280.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
54e98699
MM
1729*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1730*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1731*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1732*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1733 unsigned_word EA;
1734 if (RA == 0 || RA == RT)
1735 program_interrupt(processor, cia,
1736 illegal_instruction_program_interrupt);
1737 EA = *rA + EXTS(D);
1738 *rT = MEM(unsigned, EA, 4);
1739 *rA = EA;
45525d8d 1740 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1741
c143ef62 17420.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
54e98699
MM
1743*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1744*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1745*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1746*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1747 unsigned_word EA;
1748 if (RA == 0 || RA == RT)
1749 program_interrupt(processor, cia,
1750 illegal_instruction_program_interrupt);
1751 EA = *rA + *rB;
1752 *rT = MEM(unsigned, EA, 4);
1753 *rA = EA;
45525d8d 1754 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1755
17560.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1757# unsigned_word b;
1758# unsigned_word EA;
1759# if (RA == 0) b = 0;
1760# else b = *rA;
1761# EA = b + EXTS(DS_0b00);
1762# *rT = MEM(signed, EA, 4);
845ff5a4 1763
c143ef62
MM
17640.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1765# unsigned_word b;
1766# unsigned_word EA;
1767# if (RA == 0) b = 0;
1768# else b = *rA;
1769# EA = b + *rB;;
1770# *rT = MEM(signed, EA, 4);
845ff5a4 1771
c143ef62
MM
17720.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1773# unsigned_word EA;
1774# if (RA == 0 || RA == RT)
1775# program_interrupt(processor, cia
1776# illegal_instruction_program_interrupt);
1777# EA = *rA + *rB;
1778# *rT = MEM(signed, EA, 4);
1779# *rA = EA;
1780
17810.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1782# unsigned_word b;
1783# unsigned_word EA;
1784# if (RA == 0) b = 0;
1785# else b = *rA;
1786# EA = b + EXTS(DS_0b00);
1787# *rT = MEM(unsigned, EA, 8);
845ff5a4 1788
c143ef62
MM
17890.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1790# unsigned_word b;
1791# unsigned_word EA;
1792# if (RA == 0) b = 0;
1793# else b = *rA;
1794# EA = b + *rB;
1795# *rT = MEM(unsigned, EA, 8);
845ff5a4 1796
c143ef62
MM
17970.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1798# unsigned_word EA;
1799# if (RA == 0 || RA == RT)
1800# program_interrupt(processor, cia
1801# illegal_instruction_program_interrupt);
1802# EA = *rA + EXTS(DS_0b00);
1803# *rT = MEM(unsigned, EA, 8);
1804# *rA = EA;
845ff5a4 1805
c143ef62
MM
18060.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1807# unsigned_word EA;
1808# if (RA == 0 || RA == RT)
1809# program_interrupt(processor, cia
1810# illegal_instruction_program_interrupt);
1811# EA = *rA + *rB;
1812# *rT = MEM(unsigned, EA, 8);
1813# *rA = EA;
1814
1815
1816
1817#
1818# I.3.3.3 Fixed-Point Store Instructions
1819#
1820
18210.38,6.RS,11.RA,16.D:D:::Store Byte
54e98699
MM
1822*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1823*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1824*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1825*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1826 unsigned_word b;
1827 unsigned_word EA;
1828 if (RA == 0) b = 0;
1829 else b = *rA;
1830 EA = b + EXTS(D);
1831 STORE(EA, 1, *rS);
45525d8d 1832 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
845ff5a4 1833
c143ef62 18340.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
54e98699
MM
1835*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1836*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1837*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1838*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1839 unsigned_word b;
1840 unsigned_word EA;
1841 if (RA == 0) b = 0;
1842 else b = *rA;
1843 EA = b + *rB;
1844 STORE(EA, 1, *rS);
45525d8d 1845 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 1846
c143ef62 18470.39,6.RS,11.RA,16.D:D:::Store Byte with Update
54e98699
MM
1848*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1849*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1850*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1851*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1852 unsigned_word EA;
1853 if (RA == 0)
1854 program_interrupt(processor, cia,
1855 illegal_instruction_program_interrupt);
1856 EA = *rA + EXTS(D);
1857 STORE(EA, 1, *rS);
1858 *rA = EA;
45525d8d 1859 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
845ff5a4 1860
c143ef62 18610.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
54e98699
MM
1862*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1863*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1864*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1865*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1866 unsigned_word EA;
1867 if (RA == 0)
1868 program_interrupt(processor, cia,
1869 illegal_instruction_program_interrupt);
1870 EA = *rA + *rB;
1871 STORE(EA, 1, *rS);
1872 *rA = EA;
45525d8d 1873 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
1874
18750.44,6.RS,11.RA,16.D:D:::Store Half Word
54e98699
MM
1876*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1877*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1878*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1879*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1880 unsigned_word b;
1881 unsigned_word EA;
1882 if (RA == 0) b = 0;
1883 else b = *rA;
1884 EA = b + EXTS(D);
1885 STORE(EA, 2, *rS);
45525d8d 1886 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
845ff5a4 1887
c143ef62 18880.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
54e98699
MM
1889*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1890*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1891*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1892*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1893 unsigned_word b;
1894 unsigned_word EA;
1895 if (RA == 0) b = 0;
1896 else b = *rA;
1897 EA = b + *rB;
1898 STORE(EA, 2, *rS);
45525d8d 1899 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 1900
c143ef62 19010.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
54e98699
MM
1902*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1903*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1904*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1905*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1906 unsigned_word EA;
1907 if (RA == 0)
1908 program_interrupt(processor, cia,
1909 illegal_instruction_program_interrupt);
1910 EA = *rA + EXTS(D);
1911 STORE(EA, 2, *rS);
1912 *rA = EA;
45525d8d 1913 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
845ff5a4 1914
c143ef62 19150.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
54e98699
MM
1916*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1917*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1918*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1919*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1920 unsigned_word EA;
1921 if (RA == 0)
1922 program_interrupt(processor, cia,
1923 illegal_instruction_program_interrupt);
1924 EA = *rA + *rB;
1925 STORE(EA, 2, *rS);
1926 *rA = EA;
45525d8d 1927 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
1928
19290.36,6.RS,11.RA,16.D:D:::Store Word
54e98699
MM
1930*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1931*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1932*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1933*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1934 unsigned_word b;
1935 unsigned_word EA;
1936 if (RA == 0) b = 0;
1937 else b = *rA;
1938 EA = b + EXTS(D);
1939 STORE(EA, 4, *rS);
45525d8d 1940 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
845ff5a4 1941
c143ef62 19420.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
54e98699
MM
1943*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1944*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1945*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1946*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1947 unsigned_word b;
1948 unsigned_word EA;
1949 if (RA == 0) b = 0;
1950 else b = *rA;
1951 EA = b + *rB;
1952 STORE(EA, 4, *rS);
45525d8d 1953 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 1954
c143ef62 19550.37,6.RS,11.RA,16.D:D:::Store Word with Update
54e98699
MM
1956*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1957*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1958*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1959*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1960 unsigned_word EA;
1961 if (RA == 0)
1962 program_interrupt(processor, cia,
1963 illegal_instruction_program_interrupt);
1964 EA = *rA + EXTS(D);
1965 STORE(EA, 4, *rS);
1966 *rA = EA;
45525d8d 1967 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
845ff5a4 1968
c143ef62 19690.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
54e98699
MM
1970*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1971*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1972*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1973*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1974 unsigned_word EA;
1975 if (RA == 0)
1976 program_interrupt(processor, cia,
1977 illegal_instruction_program_interrupt);
1978 EA = *rA + *rB;
1979 STORE(EA, 4, *rS);
1980 *rA = EA;
45525d8d 1981 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
1982
19830.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
1984# unsigned_word b;
1985# unsigned_word EA;
1986# if (RA == 0) b = 0;
1987# else b = *rA;
1988# EA = b + EXTS(DS_0b00);
1989# STORE(EA, 8, *rS);
19900.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
1991# unsigned_word b;
1992# unsigned_word EA;
1993# if (RA == 0) b = 0;
1994# else b = *rA;
1995# EA = b + *rB;
1996# STORE(EA, 8, *rS);
19970.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
1998# unsigned_word EA;
1999# if (RA == 0)
2000# program_interrupt(processor, cia
2001# illegal_instruction_program_interrupt);
2002# EA = *rA + EXTS(DS_0b00);
2003# STORE(EA, 8, *rS);
2004# *rA = EA;
20050.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2006# unsigned_word EA;
2007# if (RA == 0)
2008# program_interrupt(processor, cia
2009# illegal_instruction_program_interrupt);
2010# EA = *rA + *rB;
2011# STORE(EA, 8, *rS);
2012# *rA = EA;
2013
2014
2015#
2016# I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2017#
2018
20190.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
54e98699
MM
2020*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2021*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2022*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2023*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2024 unsigned_word b;
2025 unsigned_word EA;
2026 if (RA == 0) b = 0;
2027 else b = *rA;
2028 EA = b + *rB;
2029 *rT = SWAP_2(MEM(unsigned, EA, 2));
45525d8d 2030 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 2031
c143ef62 20320.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
54e98699
MM
2033*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2034*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2035*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2036*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2037 unsigned_word b;
2038 unsigned_word EA;
2039 if (RA == 0) b = 0;
2040 else b = *rA;
2041 EA = b + *rB;
2042 *rT = SWAP_4(MEM(unsigned, EA, 4));
45525d8d 2043 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
2044
20450.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
54e98699
MM
2046*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2047*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2048*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2049*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2050 unsigned_word b;
2051 unsigned_word EA;
2052 if (RA == 0) b = 0;
2053 else b = *rA;
2054 EA = b + *rB;
2055 STORE(EA, 2, SWAP_2(*rS));
45525d8d 2056 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 2057
c143ef62 20580.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
54e98699
MM
2059*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2060*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2061*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2062*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2063 unsigned_word b;
2064 unsigned_word EA;
2065 if (RA == 0) b = 0;
2066 else b = *rA;
2067 EA = b + *rB;
2068 STORE(EA, 4, SWAP_4(*rS));
45525d8d 2069 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
2070
2071
2072#
2073# I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2074#
2075
20760.46,6.RT,11.RA,16.D:D:be::Load Multiple Word
845ff5a4 2077
c143ef62
MM
20780.47,6.RS,11.RA,16.D:D:be::Store Multiple Word
2079
2080
2081#
2082# I.3.3.6 Fixed-Point Move Assist Instructions
2083#
2084
20850.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate
845ff5a4 2086
c143ef62
MM
20870.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed
2088
20890.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate
845ff5a4 2090
c143ef62
MM
20910.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed
2092
2093
2094#
2095# I.3.3.7 Storage Synchronization Instructions
2096#
2097# HACK: Rather than monitor addresses looking for a reason
2098# to cancel a reservation. This code instead keeps
2099# a copy of the data read from memory. Before performing
2100# a store, the memory area is checked to see if it has
2101# been changed.
21020.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
54e98699
MM
2103*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2104*603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2105*603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2106*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
2107 unsigned_word b;
2108 unsigned_word EA;
2109 if (RA == 0) b = 0;
2110 else b = *rA;
2111 EA = b + *rB;
2112 RESERVE = 1;
2113 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2114 RESERVE_DATA = MEM(unsigned, EA, 4);
2115 *rT = RESERVE_DATA;
45525d8d 2116 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 2117
c143ef62
MM
21180.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2119 unsigned_word b;
2120 unsigned_word EA;
2121 if (RA == 0) b = 0;
2122 else b = *rA;
2123 EA = b + *rB;
2124 RESERVE = 1;
2125 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2126 RESERVE_DATA = MEM(unsigned, EA, 8);
2127 *rT = RESERVE_DATA;
45525d8d 2128 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
2129
21300.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
54e98699
MM
2131*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2132*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2133*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2134*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
c143ef62
MM
2135 unsigned_word b;
2136 unsigned_word EA;
2137 if (RA == 0) b = 0;
2138 else b = *rA;
2139 EA = b + *rB;
2140 if (RESERVE) {
2141 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2142 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2143 STORE(EA, 4, *rS);
2144 CR_SET_XER_SO(0, cr_i_zero);
2145 }
2146 else {
2147 /* ment to randomly to store, we never do! */
2148 CR_SET_XER_SO(0, 0);
2149 }
2150 RESERVE = 0;
2151 }
2152 else {
2153 CR_SET_XER_SO(0, 0);
2154 }
45525d8d
MM
2155 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2156
c143ef62
MM
21570.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2158 unsigned_word b;
2159 unsigned_word EA;
2160 if (RA == 0) b = 0;
2161 else b = *rA;
2162 EA = b + *rB;
2163 if (RESERVE) {
2164 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2165 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2166 STORE(EA, 8, *rS);
2167 CR_SET_XER_SO(0, cr_i_zero);
2168 }
2169 else {
2170 /* ment to randomly to store, we never do */
2171 CR_SET_XER_SO(0, 0);
2172 }
2173 RESERVE = 0;
2174 }
2175 else {
2176 CR_SET_XER_SO(0, 0);
2177 }
45525d8d 2178 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
c143ef62
MM
2179
21800.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
54e98699
MM
2181*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2182*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2183*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2184*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
c143ef62
MM
2185 /* do nothing */
2186
2187
2188#
2189# I.3.3.9 Fixed-Point Arithmetic Instructions
2190#
2191
21920.14,6.RT,11.RA,16.SI:D:T::Add Immediate
54e98699
MM
2193*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2194*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2195*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2196*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
45525d8d
MM
2197 if (RA_is_0) *rT = EXTS(SI);
2198 else *rT = *rA + EXTS(SI);
2199 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
80948f39 2200
c143ef62 22010.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
54e98699
MM
2202*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2203*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2204*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2205*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
45525d8d
MM
2206 if (RA_is_0) *rT = EXTS(SI) << 16;
2207 else *rT = *rA + (EXTS(SI) << 16);
2208 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
80948f39 2209
c143ef62 22100.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
54e98699
MM
2211*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2212*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2213*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2214*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2215 ALU_BEGIN(*rA);
2216 ALU_ADD(*rB);
2217 ALU_END(*rT, 0/*CA*/, OE, Rc);
45525d8d 2218 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2219
c143ef62 22200.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
54e98699
MM
2221*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2222*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2223*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2224*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2225 ALU_BEGIN(*rA);
2226 ALU_NOT;
2227 ALU_ADD(*rB);
2228 ALU_ADD(1);
2229 ALU_END(*rT, 0/*CA*/, OE, Rc);
45525d8d 2230 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2231
c143ef62 22320.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
54e98699
MM
2233*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2234*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2235*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2236*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2237 ALU_BEGIN(*rA);
2238 ALU_ADD(EXTS(SI));
2239 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
45525d8d 2240 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
80948f39 2241
c143ef62 22420.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
54e98699
MM
2243*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2244*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2245*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2246*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2247 ALU_BEGIN(*rA);
2248 ALU_ADD(EXTS(SI));
2249 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
45525d8d 2250 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
80948f39 2251
c143ef62 22520.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
54e98699
MM
2253*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2254*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2255*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2256*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2257 ALU_BEGIN(*rA);
2258 ALU_NOT;
2259 ALU_ADD(EXTS(SI));
2260 ALU_ADD(1);
2261 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
45525d8d 2262 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
80948f39 2263
c143ef62 22640.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
54e98699
MM
2265*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2266*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2267*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2268*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2269 ALU_BEGIN(*rA);
2270 ALU_ADD(*rB);
2271 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2272 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2273
c143ef62 22740.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
54e98699
MM
2275*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2276*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2277*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2278*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2279 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2280 ALU_BEGIN(*rA);
2281 ALU_NOT;
2282 ALU_ADD(*rB);
2283 ALU_ADD(1);
2284 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2285 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2286
c143ef62 22870.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
54e98699
MM
2288*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2289*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2290*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2291*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2292 ALU_BEGIN(*rA);
2293 ALU_ADD(*rB);
2294 ALU_ADD_CA;
2295 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2296 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2297
c143ef62 22980.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
54e98699
MM
2299*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2300*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2301*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2302*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2303 ALU_BEGIN(*rA);
2304 ALU_NOT;
2305 ALU_ADD(*rB);
2306 ALU_ADD_CA;
2307 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2308 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2309
c143ef62 23100.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
54e98699
MM
2311*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2312*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2313*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2314*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2315# ALU_BEGIN(*rA);
2316# ALU_ADD_CA;
2317# ALU_SUB(1);
2318# ALU_END(*rT, 1/*CA*/, OE, Rc);
80948f39 2319
c143ef62 23200.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
54e98699
MM
2321*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2322*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2323*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2324*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2325# ALU_BEGIN(*rA);
2326# ALU_NOT;
2327# ALU_ADD_CA;
2328# ALU_SUB(1);
2329# ALU_END(*rT, 1/*CA*/, OE, Rc);
80948f39 2330
c143ef62 23310.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
54e98699
MM
2332*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2333*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2334*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2335*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2336 ALU_BEGIN(*rA);
2337 ALU_ADD_CA;
2338 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2339 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2340
c143ef62 23410.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
54e98699
MM
2342*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2343*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2344*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2345*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2346 ALU_BEGIN(*rA);
2347 ALU_NOT;
2348 ALU_ADD_CA;
2349 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2350 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2351
c143ef62 23520.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
54e98699
MM
2353*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2354*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2355*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2356*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2357 ALU_BEGIN(*rA);
2358 ALU_NOT;
2359 ALU_ADD(1);
2360 ALU_END(*rT,0/*CA*/,OE,Rc);
45525d8d 2361 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2362
c143ef62 23630.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
54e98699
MM
2364*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2365*603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2366*603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2367*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62
MM
2368 signed_word prod = *rA * EXTS(SI);
2369 *rT = prod;
45525d8d 2370 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
80948f39 2371
c143ef62 23720.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
80948f39 2373
c143ef62 23740.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
54e98699
MM
2375*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2376*603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2377*603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2378*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
c143ef62
MM
2379 signed64 a = (signed32)(*rA);
2380 signed64 b = (signed32)(*rB);
2381 signed64 prod = a * b;
2382 signed_word t = prod;
2383 *rT = *rA * *rB;
2384 if (t != prod && OE)
2385 XER |= (xer_overflow | xer_summary_overflow);
2386 CR0_COMPARE(t, 0, Rc);
45525d8d 2387 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2388
c143ef62 23890.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
80948f39 2390
c143ef62 23910.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
54e98699
MM
2392*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2393*603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2394*603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2395*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
c143ef62
MM
2396 signed64 a = (signed32)(*rA);
2397 signed64 b = (signed32)(*rB);
2398 signed64 prod = a * b;
2399 signed_word t = EXTRACTED64(prod, 0, 31);
2400 *rT = t;
2401 CR0_COMPARE(t, 0, Rc);
45525d8d 2402 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2403
c143ef62 24040.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
80948f39 2405
c143ef62 24060.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
54e98699
MM
2407*601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2408*603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2409*603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2410*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
c143ef62
MM
2411 unsigned64 a = (unsigned32)(*rA);
2412 unsigned64 b = (unsigned32)(*rB);
2413 unsigned64 prod = a * b;
2414 signed_word t = EXTRACTED64(prod, 0, 31);
2415 *rT = t;
2416 CR0_COMPARE(t, 0, Rc);
45525d8d 2417 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2418
c143ef62 24190.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
80948f39 2420
c143ef62 24210.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
54e98699
MM
2422*601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2423*603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2424*603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2425*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
c143ef62
MM
2426 signed64 dividend = (signed32)(*rA);
2427 signed64 divisor = (signed32)(*rB);
2428 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2429 || (dividend == 0x80000000 && divisor == -1)) {
2430 if (OE)
2431 XER |= (xer_overflow | xer_summary_overflow);
2432 CR0_COMPARE(0, 0, Rc);
2433 }
2434 else {
2435 signed64 quotent = dividend / divisor;
2436 *rT = quotent;
2437 CR0_COMPARE((signed_word)quotent, 0, Rc);
2438 }
45525d8d 2439 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
54e98699 2440
c143ef62 24410.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
80948f39 2442
c143ef62 24430.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
54e98699
MM
2444*601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2445*603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2446*603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2447*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
c143ef62
MM
2448 unsigned64 dividend = (unsigned32)(*rA);
2449 unsigned64 divisor = (unsigned32)(*rB);
2450 if (divisor == 0) {
2451 if (OE)
2452 XER |= (xer_overflow | xer_summary_overflow);
2453 CR0_COMPARE(0, 0, Rc);
2454 }
2455 else {
2456 unsigned64 quotent = dividend / divisor;
2457 *rT = quotent;
2458 CR0_COMPARE((signed_word)quotent, 0, Rc);
2459 }
45525d8d 2460 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
c143ef62
MM
2461
2462
2463#
2464# I.3.3.10 Fixed-Point Compare Instructions
2465#
2466
24670.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
54e98699
MM
2468*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2469*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2470*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2471*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2472 if (!is_64bit_mode && L)
2473 program_interrupt(processor, cia,
2474 illegal_instruction_program_interrupt);
2475 else {
2476 signed_word a;
2477 signed_word b = EXTS(SI);
2478 if (L == 0)
2479 a = EXTENDED(*rA);
2480 else
2481 a = *rA;
2482 CR_COMPARE(BF, a, b);
2483 }
45525d8d 2484 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
845ff5a4 2485
c143ef62 24860.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
54e98699
MM
2487*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2488*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2489*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2490*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2491 if (!is_64bit_mode && L)
2492 program_interrupt(processor, cia,
2493 illegal_instruction_program_interrupt);
2494 else {
2495 signed_word a;
2496 signed_word b;
2497 if (L == 0) {
2498 a = EXTENDED(*rA);
2499 b = EXTENDED(*rB);
2500 }
2501 else {
2502 a = *rA;
2503 b = *rB;
2504 }
2505 CR_COMPARE(BF, a, b);
2506 }
45525d8d 2507 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
845ff5a4 2508
c143ef62 25090.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
54e98699
MM
2510*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2511*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2512*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2513*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2514 if (!is_64bit_mode && L)
2515 program_interrupt(processor, cia,
2516 illegal_instruction_program_interrupt);
2517 else {
2518 unsigned_word a;
2519 unsigned_word b = UI;
2520 if (L == 0)
2521 a = MASKED(*rA, 32, 63);
2522 else
2523 a = *rA;
2524 CR_COMPARE(BF, a, b);
2525 }
45525d8d 2526 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
845ff5a4 2527
c143ef62 25280.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
54e98699
MM
2529*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2530*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2531*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2532*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2533 if (!is_64bit_mode && L)
2534 program_interrupt(processor, cia,
2535 illegal_instruction_program_interrupt);
2536 else {
2537 unsigned_word a;
2538 unsigned_word b;
2539 if (L == 0) {
2540 a = MASKED(*rA, 32, 63);
2541 b = MASKED(*rB, 32, 63);
2542 }
2543 else {
2544 a = *rA;
2545 b = *rB;
2546 }
2547 CR_COMPARE(BF, a, b);
2548 }
45525d8d 2549 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
c143ef62
MM
2550
2551
2552#
2553# I.3.3.11 Fixed-Point Trap Instructions
2554#
2555
25560.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2557 if (!is_64bit_mode)
2558 program_interrupt(processor, cia,
2559 illegal_instruction_program_interrupt);
2560 else {
2561 signed_word a = *rA;
2562 signed_word b = EXTS(SI);
2563 if ((a < b && TO{0})
2564 || (a > b && TO{1})
2565 || (a == b && TO{2})
2566 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2567 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2568 )
2569 program_interrupt(processor, cia,
2570 trap_program_interrupt);
2571 }
845ff5a4 2572
c143ef62 25730.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
54e98699
MM
2574*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2575*603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2576*603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2577*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2578 signed_word a = EXTENDED(*rA);
2579 signed_word b = EXTS(SI);
2580 if ((a < b && TO{0})
2581 || (a > b && TO{1})
2582 || (a == b && TO{2})
2583 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2584 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2585 )
2586 program_interrupt(processor, cia,
2587 trap_program_interrupt);
845ff5a4 2588
c143ef62
MM
25890.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2590 if (!is_64bit_mode)
2591 program_interrupt(processor, cia,
2592 illegal_instruction_program_interrupt);
2593 else {
2594 signed_word a = *rA;
2595 signed_word b = *rB;
2596 if ((a < b && TO{0})
2597 || (a > b && TO{1})
2598 || (a == b && TO{2})
2599 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2600 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2601 )
2602 program_interrupt(processor, cia,
2603 trap_program_interrupt);
2604 }
845ff5a4 2605
c143ef62 26060.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
54e98699
MM
2607*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2608*603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2609*603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2610*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2611 signed_word a = EXTENDED(*rA);
2612 signed_word b = EXTENDED(*rB);
2613 if (TO == 12 && rA == rB) {
2614 ITRACE(trace_breakpoint, ("breakpoint\n"));
2615 cpu_halt(processor, cia, was_trap, 0);
2616 }
2617 else if ((a < b && TO{0})
2618 || (a > b && TO{1})
2619 || (a == b && TO{2})
2620 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2621 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2622 )
2623 program_interrupt(processor, cia,
2624 trap_program_interrupt);
2625
2626#
2627# I.3.3.12 Fixed-Point Logical Instructions
2628#
2629
26300.28,6.RS,11.RA,16.UI:D:::AND Immediate
54e98699
MM
2631*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2632*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2633*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2634*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2635 *rA = *rS & UI;
2636 CR0_COMPARE(*rA, 0, 1/*Rc*/);
45525d8d 2637 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
845ff5a4 2638
c143ef62 26390.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
54e98699
MM
2640*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2641*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2642*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2643*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2644 *rA = *rS & (UI << 16);
2645 CR0_COMPARE(*rA, 0, 1/*Rc*/);
45525d8d 2646 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
845ff5a4 2647
c143ef62 26480.24,6.RS,11.RA,16.UI:D:::OR Immediate
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;
45525d8d 2654 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2655
c143ef62 26560.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
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 << 16);
45525d8d 2662 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2663
c143ef62 26640.26,6.RS,11.RA,16.UI:D:::XOR Immediate
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;
45525d8d 2670 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2671
c143ef62 26720.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
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 2677 *rA = *rS ^ (UI << 16);
45525d8d 2678 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2679
c143ef62 26800.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
54e98699
MM
2681*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2682*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2683*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2684*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2685 *rA = *rS & *rB;
2686 CR0_COMPARE(*rA, 0, Rc);
45525d8d 2687 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2688
c143ef62 26890.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
54e98699
MM
2690*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2691*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2692*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2693*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2694 *rA = *rS | *rB;
2695 CR0_COMPARE(*rA, 0, Rc);
45525d8d 2696 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2697
c143ef62 26980.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
54e98699
MM
2699*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2700*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2701*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2702*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2703 *rA = *rS ^ *rB;
2704 CR0_COMPARE(*rA, 0, Rc);
45525d8d 2705 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2706
c143ef62 27070.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
54e98699
MM
2708*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2709*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2710*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2711*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2712 *rA = ~(*rS & *rB);
2713 CR0_COMPARE(*rA, 0, Rc);
45525d8d 2714 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2715
c143ef62 27160.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
54e98699
MM
2717*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2718*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2719*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2720*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2721 *rA = ~(*rS | *rB);
2722 CR0_COMPARE(*rA, 0, Rc);
45525d8d 2723 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2724
c143ef62 27250.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
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); /* A === B */
2731# CR0_COMPARE(*rA, 0, Rc);
845ff5a4 2732
c143ef62 27330.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
54e98699
MM
2734*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2735*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2736*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2737*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2738 *rA = *rS & ~*rB;
2739 CR0_COMPARE(*rA, 0, Rc);
45525d8d 2740 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
54e98699 2741
c143ef62 27420.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
54e98699
MM
2743*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2744*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2745*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2746*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2747 *rA = *rS | ~*rB;
2748 CR0_COMPARE(*rA, 0, Rc);
45525d8d 2749 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2750
c143ef62 27510.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
54e98699
MM
2752*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2753*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2754*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2755*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2756 *rA = (signed_word)(signed8)*rS;
2757 CR0_COMPARE(*rA, 0, Rc);
45525d8d 2758 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 2759
c143ef62 27600.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
54e98699
MM
2761*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2762*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2763*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2764*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2765 *rA = (signed_word)(signed16)*rS;
2766 CR0_COMPARE(*rA, 0, Rc);
45525d8d 2767 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 2768
c143ef62 27690.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
54e98699
MM
2770*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2771*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2772*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2773*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2774# *rA = (signed_word)(signed32)*rS;
2775# CR0_COMPARE(*rA, 0, Rc);
845ff5a4 2776
c143ef62
MM
27770.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2778# int count = 0;
2779# unsigned64 mask = BIT64(0);
2780# unsigned64 source = *rS;
2781# while (!(source & mask) && mask != 0) {
2782# mask >>= 1;
2783# count++;
2784# }
2785# *rA = count;
2786# CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
845ff5a4 2787
c143ef62 27880.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
54e98699
MM
2789*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2790*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2791*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2792*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2793 int count = 0;
2794 unsigned32 mask = BIT32(0);
2795 unsigned32 source = *rS;
2796 while (!(source & mask) && mask != 0) {
2797 mask >>= 1;
2798 count++;
2799 }
2800 *rA = count;
2801 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2802
2803
2804#
2805# I.3.3.13 Fixed-Point Rotate and Shift Instructions
2806#
2807
28080.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
2809# long n = (sh_5 << 4) | sh_0_4;
2810# unsigned_word r = ROTL64(*rS, n);
2811# long b = (mb_5 << 4) | mb_0_4;
2812# unsigned_word m = MASK(b, 63);
2813# signed_word result = r & m;
2814# *rA = result;
2815# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
845ff5a4 2816
c143ef62
MM
28170.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
2818# long n = (sh_5 << 4) | sh_0_4;
2819# unsigned_word r = ROTL64(*rS, n);
2820# long e = (me_5 << 4) | me_0_4;
2821# unsigned_word m = MASK(0, e);
2822# signed_word result = r & m;
2823# *rA = result;
2824# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
845ff5a4 2825
c143ef62
MM
28260.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
2827# long n = (sh_5 << 4) | sh_0_4;
2828# unsigned_word r = ROTL64(*rS, n);
2829# long b = (mb_5 << 4) | mb_0_4;
2830# unsigned_word m = MASK(0, (64-n));
2831# signed_word result = r & m;
2832# *rA = result;
2833# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2834
28350.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
54e98699
MM
2836*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2837*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2838*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2839*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2840 long n = SH;
2841 unsigned32 s = *rS;
2842 unsigned32 r = ROTL32(s, n);
2843 unsigned32 m = MASK(MB+32, ME+32);
2844 signed_word result = r & m;
2845 *rA = result;
2846 CR0_COMPARE(result, 0, Rc);
2847 ITRACE(trace_alu,
45525d8d
MM
2848 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
2849 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
2850 (unsigned long)result, (unsigned long)CR));
2851 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
2852
28530.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2854# long n = MASKED(*rB, 58, 63);
2855# unsigned_word r = ROTL64(*rS, n);
2856# long b = (mb_5 << 4) | mb_0_4;
2857# unsigned_word m = MASK(b, 63);
2858# signed_word result = r & m;
2859# *rA = result;
2860# CR0_COMPARE(result, 0, Rc);
845ff5a4 2861
c143ef62
MM
28620.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2863# long n = MASKED(*rB, 58, 63);
2864# unsigned_word r = ROTL64(*rS, n);
2865# long e = (me_5 << 4) | me_0_4;
2866# unsigned_word m = MASK(0, e);
2867# signed_word result = r & m;
2868# *rA = result;
2869# CR0_COMPARE(result, 0, Rc);
2870
28710.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2872# long n = MASKED(*rB, 59, 63);
2873# unsigned32 r = ROTL32(*rS, n);
2874# unsigned32 m = MASK(MB+32, ME+32);
2875# signed_word result = r & m;
2876# *rA = result;
2877# CR0_COMPARE(result, 0, Rc);
845ff5a4 2878
c143ef62
MM
28790.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
2880# long n = (sh_5 << 4) | sh_0_4;
2881# unsigned_word r = ROTL64(*rS, n);
2882# long b = (mb_5 << 4) | mb_0_4;
2883# unsigned_word m = MASK(b, (64-n));
2884# signed_word result = (r & m) | (*rA & ~m)
2885# *rA = result;
2886# CR0_COMPARE(result, 0, Rc);
845ff5a4 2887
c143ef62 28880.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
54e98699
MM
2889*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2890*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2891*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2892*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2893 long n = SH;
2894 unsigned32 r = ROTL32(*rS, n);
2895 unsigned32 m = MASK(MB+32, ME+32);
2896 signed_word result = (r & m) | (*rA & ~m);
2897 *rA = result;
45525d8d
MM
2898 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
2899 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
2900 (unsigned long)result));
c143ef62 2901 CR0_COMPARE(result, 0, Rc);
45525d8d 2902 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
2903
2904
29050.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
845ff5a4 2906
c143ef62 29070.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
54e98699
MM
2908*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2909*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2910*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2911*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2912 int n = MASKED(*rB, 59, 63);
2913 unsigned32 source = *rS;
2914 signed_word shifted;
2915 if (n < 32)
2916 shifted = (source << n);
2917 else
2918 shifted = 0;
2919 *rA = shifted;
2920 CR0_COMPARE(shifted, 0, Rc);
2921 ITRACE(trace_alu,
45525d8d
MM
2922 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2923 n, (unsigned long)source, (unsigned long)shifted));
2924 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 2925
c143ef62 29260.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
845ff5a4 2927
c143ef62 29280.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
54e98699
MM
2929*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2930*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2931*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2932*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2933 int n = MASKED(*rB, 59, 63);
2934 unsigned32 source = *rS;
2935 signed_word shifted;
2936 if (n < 32)
2937 shifted = (source >> n);
2938 else
2939 shifted = 0;
2940 *rA = shifted;
2941 CR0_COMPARE(shifted, 0, Rc);
2942 ITRACE(trace_alu, \
45525d8d
MM
2943 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2944 n, (unsigned long)source, (unsigned long)shifted));
2945 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
2946
29470.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
845ff5a4 2948
c143ef62 29490.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
54e98699
MM
2950*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2951*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2952*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2953*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2954 int n = SH;
2955 signed_word r = ROTL32(*rS, /*64*/32-n);
2956 signed_word m = MASK(n+32, 63);
2957 int S = MASKED(*rS, 32, 32);
2958 signed_word shifted = (r & m) | (S ? ~m : 0);
2959 *rA = shifted;
2960 if (S && ((r & ~m) & MASK(32, 63)) != 0)
2961 XER |= xer_carry;
2962 else
2963 XER &= ~xer_carry;
2964 CR0_COMPARE(shifted, 0, Rc);
45525d8d 2965 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 2966
c143ef62 29670.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
845ff5a4 2968
c143ef62 29690.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
54e98699
MM
2970*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2971*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2972*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2973*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2974 int n = MASKED(*rB, 58, 63);
2975 int shift = (n >= 31 ? 31 : n);
2976 signed32 source = (signed32)*rS; /* signed to keep sign bit */
2977 signed32 shifted = source >> shift;
2978 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
2979 *rA = (signed_word)shifted; /* if 64bit will sign extend */
2980 if (source < 0 && (source & mask))
2981 XER |= xer_carry;
2982 else
2983 XER &= ~xer_carry;
2984 CR0_COMPARE(shifted, 0, Rc);
45525d8d 2985 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
2986
2987#
2988# I.3.3.14 Move to/from System Register Instructions
2989#
2990
f2181eff 29910.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
54e98699
MM
2992*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2993*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2994*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
2995*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
f2181eff
MM
2996 int n = (SPR{5:9} << 5) | SPR{0:4};
2997 if (SPR{0} && IS_PROBLEM_STATE(processor))
c143ef62
MM
2998 program_interrupt(processor, cia,
2999 privileged_instruction_program_interrupt);
3000 else if (!spr_is_valid(n)
3001 || spr_is_readonly(n))
3002 program_interrupt(processor, cia,
3003 illegal_instruction_program_interrupt);
3004 else {
3005 spreg new_val = (spr_length(n) == 64
3006 ? *rS
3007 : MASKED(*rS, 32, 63));
3008 /* HACK - time base registers need to be updated immediatly */
3009 if (WITH_TIME_BASE) {
c143ef62
MM
3010 switch (n) {
3011 case spr_tbu:
3012 cpu_set_time_base(processor,
80948f39
MM
3013 (MASKED64(cpu_get_time_base(processor), 32, 63)
3014 | INSERTED64(new_val, 0, 31)));
c143ef62
MM
3015 break;
3016 case spr_tbl:
3017 cpu_set_time_base(processor,
80948f39
MM
3018 (MASKED64(cpu_get_time_base(processor), 0, 31)
3019 | INSERTED64(new_val, 32, 63)));
c143ef62
MM
3020 break;
3021 case spr_dec:
3022 cpu_set_decrementer(processor, new_val);
3023 break;
3024 default:
3025 SPREG(n) = new_val;
3026 break;
3027 }
3028 }
3029 else {
3030 SPREG(n) = new_val;
3031 }
3032 }
45525d8d 3033 PPC_INSN_TO_SPR(RS_BITMASK, n);
845ff5a4 3034
f2181eff 30350.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
54e98699
MM
3036*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3037*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3038*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3039*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
f2181eff
MM
3040 int n = (SPR{5:9} << 5) | SPR{0:4};
3041 if (SPR{0} && IS_PROBLEM_STATE(processor))
c143ef62
MM
3042 program_interrupt(processor, cia,
3043 privileged_instruction_program_interrupt);
3044 else if (!spr_is_valid(n))
3045 program_interrupt(processor, cia,
3046 illegal_instruction_program_interrupt);
3047 else {
3048 /* HACK - some SPR's need to get their value extracted specially */
3049 *rT = SPREG(n);
3050 }
45525d8d 3051 PPC_INSN_FROM_SPR(RT_BITMASK, n);
845ff5a4 3052
c143ef62 30530.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
54e98699
MM
3054*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3055*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3056*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3057*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
3058 if (FXM == 0xff) {
3059 CR = *rS;
3060 }
3061 else {
3062 unsigned_word mask = 0;
3063 unsigned_word f;
3064 for (f = 0; f < 8; f++) {
3065 if (FXM & (0x80 >> f))
3066 mask |= (0xf << 4*(7-f));
3067 }
3068 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3069 }
f2181eff 3070 PPC_INSN_MTCR(RS_BITMASK, FXM);
845ff5a4 3071
c143ef62 30720.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
845ff5a4 3073
c143ef62 30740.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
54e98699
MM
3075*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3076*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3077*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3078*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62 3079 *rT = (unsigned32)CR;
45525d8d 3080 PPC_INSN_MFCR(RT_BITMASK);
c143ef62
MM
3081
3082#
3083# I.4.6.2 Floating-Point Load Instructions
3084#
3085
30860.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
54e98699
MM
3087*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3088*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3089*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3090*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3091 unsigned_word b;
3092 unsigned_word EA;
3093 if (RA == 0) b = 0;
3094 else b = *rA;
3095 EA = b + EXTS(D);
3096 *frT = DOUBLE(MEM(unsigned, EA, 4));
45525d8d 3097 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3098
c143ef62 30990.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
54e98699
MM
3100*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3101*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3102*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3103*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3104 unsigned_word b;
3105 unsigned_word EA;
3106 if (RA == 0) b = 0;
3107 else b = *rA;
3108 EA = b + *rB;
3109 *frT = DOUBLE(MEM(unsigned, EA, 4));
45525d8d 3110 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 3111
c143ef62 31120.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
54e98699
MM
3113*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3114*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3115*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3116*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3117 unsigned_word EA;
3118 if (RA == 0)
3119 program_interrupt(processor, cia,
3120 illegal_instruction_program_interrupt);
3121 EA = *rA + EXTS(D);
3122 *frT = DOUBLE(MEM(unsigned, EA, 4));
3123 *rA = EA;
45525d8d 3124 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3125
c143ef62 31260.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
54e98699
MM
3127*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3128*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3129*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3130*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3131 unsigned_word EA;
3132 if (RA == 0)
3133 program_interrupt(processor, cia,
3134 illegal_instruction_program_interrupt);
3135 EA = *rA + *rB;
3136 *frT = DOUBLE(MEM(unsigned, EA, 4));
3137 *rA = EA;
45525d8d 3138 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
3139
31400.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
54e98699
MM
3141*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3142*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3143*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3144*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3145 unsigned_word b;
3146 unsigned_word EA;
3147 if (RA == 0) b = 0;
3148 else b = *rA;
3149 EA = b + EXTS(D);
3150 *frT = MEM(unsigned, EA, 8);
45525d8d 3151 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3152
c143ef62 31530.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
54e98699
MM
3154*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3155*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3156*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3157*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3158 unsigned_word b;
3159 unsigned_word EA;
3160 if (RA == 0) b = 0;
3161 else b = *rA;
3162 EA = b + *rB;
3163 *frT = MEM(unsigned, EA, 8);
45525d8d 3164 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 3165
c143ef62 31660.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
54e98699
MM
3167*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3168*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3169*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3170*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3171 unsigned_word EA;
3172 if (RA == 0)
3173 program_interrupt(processor, cia,
3174 illegal_instruction_program_interrupt);
3175 EA = *rA + EXTS(D);
3176 *frT = MEM(unsigned, EA, 8);
3177 *rA = EA;
45525d8d 3178 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3179
c143ef62 31800.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
54e98699
MM
3181*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3182*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3183*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3184*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3185 unsigned_word EA;
3186 if (RA == 0)
3187 program_interrupt(processor, cia,
3188 illegal_instruction_program_interrupt);
3189 EA = *rA + *rB;
3190 *frT = MEM(unsigned, EA, 8);
3191 *rA = EA;
45525d8d 3192 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
3193
3194
3195#
3196# I.4.6.3 Floating-Point Store Instructions
3197#
3198
31990.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
54e98699
MM
3200*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3201*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3202*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3203*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3204 unsigned_word b;
3205 unsigned_word EA;
3206 if (RA == 0) b = 0;
3207 else b = *rA;
3208 EA = b + EXTS(D);
3209 STORE(EA, 4, SINGLE(*frS));
45525d8d 3210 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3211
c143ef62 32120.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
54e98699
MM
3213*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3214*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3215*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3216*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3217 unsigned_word b;
3218 unsigned_word EA;
3219 if (RA == 0) b = 0;
3220 else b = *rA;
3221 EA = b + *rB;
3222 STORE(EA, 4, SINGLE(*frS));
45525d8d 3223 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
845ff5a4 3224
c143ef62 32250.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
54e98699
MM
3226*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3227*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3228*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3229*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3230 unsigned_word EA;
3231 if (RA == 0)
3232 program_interrupt(processor, cia,
3233 illegal_instruction_program_interrupt);
3234 EA = *rA + EXTS(D);
3235 STORE(EA, 4, SINGLE(*frS));
3236 *rA = EA;
45525d8d 3237 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3238
c143ef62 32390.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
54e98699
MM
3240*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3241*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3242*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3243*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3244 unsigned_word EA;
3245 if (RA == 0)
3246 program_interrupt(processor, cia,
3247 illegal_instruction_program_interrupt);
3248 EA = *rA + *rB;
3249 STORE(EA, 4, SINGLE(*frS));
3250 *rA = EA;
45525d8d 3251 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
c143ef62
MM
3252
32530.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
54e98699
MM
3254*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3255*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3256*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3257*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3258 unsigned_word b;
3259 unsigned_word EA;
3260 if (RA == 0) b = 0;
3261 else b = *rA;
3262 EA = b + EXTS(D);
3263 STORE(EA, 8, *frS);
45525d8d 3264 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3265
c143ef62 32660.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
54e98699
MM
3267*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3268*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3269*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3270*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3271 unsigned_word b;
3272 unsigned_word EA;
3273 if (RA == 0) b = 0;
3274 else b = *rA;
3275 EA = b + *rB;
3276 STORE(EA, 8, *frS);
45525d8d 3277 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
845ff5a4 3278
c143ef62 32790.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
54e98699
MM
3280*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3281*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3282*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3283*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3284 unsigned_word EA;
3285 if (RA == 0)
3286 program_interrupt(processor, cia,
3287 illegal_instruction_program_interrupt);
3288 EA = *rA + EXTS(D);
3289 STORE(EA, 8, *frS);
3290 *rA = EA;
45525d8d 3291 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3292
c143ef62 32930.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
54e98699
MM
3294*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3295*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3296*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3297*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3298 unsigned_word EA;
3299 if (RA == 0)
3300 program_interrupt(processor, cia,
3301 illegal_instruction_program_interrupt);
3302 EA = *rA + *rB;
3303 STORE(EA, 8, *frS);
3304 *rA = EA;
45525d8d 3305 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
c143ef62
MM
3306
3307
3308#
3309# I.4.6.4 Floating-Point Move Instructions
3310#
3311
33120.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
54e98699
MM
3313*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3314*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3315*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3316*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3317 *frT = *frB;
3318 CR1_UPDATE(Rc);
45525d8d 3319 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 3320
c143ef62 33210.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
54e98699
MM
3322*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3323*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3324*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3325*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3326 *frT = *frB ^ BIT64(0);
3327 CR1_UPDATE(Rc);
45525d8d 3328 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 3329
c143ef62 33300.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
54e98699
MM
3331*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3332*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3333*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3334*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3335 *frT = *frB & ~BIT64(0);
3336 CR1_UPDATE(Rc);
45525d8d 3337 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 3338
c143ef62 33390.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
54e98699
MM
3340*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3341*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3342*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3343*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3344 *frT = *frB | BIT64(0);
3345 CR1_UPDATE(Rc);
45525d8d 3346 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
c143ef62
MM
3347
3348
3349#
3350# I.4.6.5 Floating-Point Arithmetic Instructions
3351#
3352
33530.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
54e98699
MM
3354*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3355*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3356*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3357*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3358 FPSCR_BEGIN;
3359 if (is_invalid_operation(processor, cia,
3360 *frA, *frB,
3361 fpscr_vxsnan | fpscr_vxisi,
3362 0, /*single?*/
3363 0) /*negate?*/) {
3364 invalid_arithemetic_operation(processor, cia,
3365 frT, *frA, *frB, 0,
3366 0, /*instruction_is_frsp*/
3367 0, /*instruction_is_convert_to_64bit*/
3368 0, /*instruction_is_convert_to_32bit*/
3369 0); /*single-precision*/
3370 }
3371 else {
3372 /*HACK!*/
3373 double s = *(double*)frA + *(double*)frB;
3374 *(double*)frT = s;
3375 }
3376 FPSCR_END(Rc);
45525d8d 3377 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
845ff5a4 3378
c143ef62 33790.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
54e98699
MM
3380*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3381*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3382*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3383*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3384 FPSCR_BEGIN;
3385 if (is_invalid_operation(processor, cia,
3386 *frA, *frB,
3387 fpscr_vxsnan | fpscr_vxisi,
3388 1, /*single?*/
3389 0) /*negate?*/) {
3390 invalid_arithemetic_operation(processor, cia,
3391 frT, *frA, *frB, 0,
3392 0, /*instruction_is_frsp*/
3393 0, /*instruction_is_convert_to_64bit*/
3394 0, /*instruction_is_convert_to_32bit*/
3395 1); /*single-precision*/
3396 }
3397 else {
3398 /*HACK!*/
3399 float s = *(double*)frA + *(double*)frB;
3400 *(double*)frT = s;
3401 }
3402 FPSCR_END(Rc);
45525d8d 3403 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
c143ef62
MM
3404
34050.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
54e98699
MM
3406*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3407*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3408*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3409*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3410 FPSCR_BEGIN;
3411 if (is_invalid_operation(processor, cia,
3412 *frA, *frB,
3413 fpscr_vxsnan | fpscr_vxisi,
3414 0, /*single?*/
3415 1) /*negate?*/) {
3416 invalid_arithemetic_operation(processor, cia,
3417 frT, *frA, *frB, 0,
3418 0, /*instruction_is_frsp*/
3419 0, /*instruction_is_convert_to_64bit*/
3420 0, /*instruction_is_convert_to_32bit*/
3421 0); /*single-precision*/
3422 }
3423 else {
3424 /*HACK!*/
3425 double s = *(double*)frA - *(double*)frB;
3426 *(double*)frT = s;
3427 }
3428 FPSCR_END(Rc);
45525d8d 3429 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
845ff5a4 3430
c143ef62 34310.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
54e98699
MM
3432*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3433*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3434*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3435*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3436 FPSCR_BEGIN;
3437 if (is_invalid_operation(processor, cia,
3438 *frA, *frB,
3439 fpscr_vxsnan | fpscr_vxisi,
3440 1, /*single?*/
3441 1) /*negate?*/) {
3442 invalid_arithemetic_operation(processor, cia,
3443 frT, *frA, *frB, 0,
3444 0, /*instruction_is_frsp*/
3445 0, /*instruction_is_convert_to_64bit*/
3446 0, /*instruction_is_convert_to_32bit*/
3447 1); /*single-precision*/
3448 }
3449 else {
3450 /*HACK!*/
3451 float s = *(double*)frA - *(double*)frB;
3452 *(double*)frT = s;
3453 }
3454 FPSCR_END(Rc);
45525d8d 3455 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
c143ef62
MM
3456
34570.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
54e98699
MM
3458*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3459*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3460*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3461*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3462 FPSCR_BEGIN;
3463 if (is_invalid_operation(processor, cia,
3464 *frA, *frC,
3465 fpscr_vxsnan | fpscr_vximz,
3466 0, /*single?*/
3467 0) /*negate?*/) {
3468 invalid_arithemetic_operation(processor, cia,
3469 frT, *frA, 0, *frC,
3470 0, /*instruction_is_frsp*/
3471 0, /*instruction_is_convert_to_64bit*/
3472 0, /*instruction_is_convert_to_32bit*/
3473 0); /*single-precision*/
3474 }
3475 else {
3476 /*HACK!*/
3477 double s = *(double*)frA * *(double*)frC;
3478 *(double*)frT = s;
3479 }
3480 FPSCR_END(Rc);
45525d8d 3481 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3482
c143ef62 34830.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
54e98699
MM
3484*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3485*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3486*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3487*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3488 FPSCR_BEGIN;
3489 if (is_invalid_operation(processor, cia,
3490 *frA, *frC,
3491 fpscr_vxsnan | fpscr_vximz,
3492 1, /*single?*/
3493 0) /*negate?*/) {
3494 invalid_arithemetic_operation(processor, cia,
3495 frT, *frA, 0, *frC,
3496 0, /*instruction_is_frsp*/
3497 0, /*instruction_is_convert_to_64bit*/
3498 0, /*instruction_is_convert_to_32bit*/
3499 1); /*single-precision*/
3500 }
3501 else {
3502 /*HACK!*/
3503 float s = *(double*)frA * *(double*)frC;
3504 *(double*)frT = s;
3505 }
3506 FPSCR_END(Rc);
45525d8d 3507 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3508
35090.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
54e98699
MM
3510*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3511*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3512*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3513*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
c143ef62
MM
3514 FPSCR_BEGIN;
3515 if (is_invalid_operation(processor, cia,
3516 *frA, *frB,
3517 fpscr_vxsnan | fpscr_vxzdz,
3518 0, /*single?*/
3519 0) /*negate?*/) {
3520 invalid_arithemetic_operation(processor, cia,
3521 frT, *frA, *frB, 0,
3522 0, /*instruction_is_frsp*/
3523 0, /*instruction_is_convert_to_64bit*/
3524 0, /*instruction_is_convert_to_32bit*/
3525 0); /*single-precision*/
3526 }
3527 else {
3528 /*HACK!*/
3529 double s = *(double*)frA / *(double*)frB;
3530 *(double*)frT = s;
3531 }
3532 FPSCR_END(Rc);
45525d8d 3533 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
845ff5a4 3534
c143ef62 35350.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
54e98699
MM
3536*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3537*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3538*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3539*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
c143ef62
MM
3540 FPSCR_BEGIN;
3541 if (is_invalid_operation(processor, cia,
3542 *frA, *frB,
3543 fpscr_vxsnan | fpscr_vxzdz,
3544 1, /*single?*/
3545 0) /*negate?*/) {
3546 invalid_arithemetic_operation(processor, cia,
3547 frT, *frA, *frB, 0,
3548 0, /*instruction_is_frsp*/
3549 0, /*instruction_is_convert_to_64bit*/
3550 0, /*instruction_is_convert_to_32bit*/
3551 1); /*single-precision*/
3552 }
3553 else {
3554 /*HACK!*/
3555 float s = *(double*)frA / *(double*)frB;
3556 *(double*)frT = s;
3557 }
3558 FPSCR_END(Rc);
45525d8d 3559 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
c143ef62
MM
3560
35610.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
54e98699
MM
3562*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3563*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3564*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3565*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3566 FPSCR_BEGIN;
3567 double product; /*HACK! - incorrectly loosing precision ... */
3568 /* compute the multiply */
3569 if (is_invalid_operation(processor, cia,
3570 *frA, *frC,
3571 fpscr_vxsnan | fpscr_vximz,
3572 0, /*single?*/
3573 0) /*negate?*/) {
3574 invalid_arithemetic_operation(processor, cia,
3575 (unsigned64*)&product, *frA, 0, *frC,
3576 0, /*instruction_is_frsp*/
3577 0, /*instruction_is_convert_to_64bit*/
3578 0, /*instruction_is_convert_to_32bit*/
3579 0); /*single-precision*/
3580 }
3581 else {
3582 /*HACK!*/
3583 product = *(double*)frA * *(double*)frC;
3584 }
3585 /* compute the add */
3586 if (is_invalid_operation(processor, cia,
3587 product, *frB,
3588 fpscr_vxsnan | fpscr_vxisi,
3589 0, /*single?*/
3590 0) /*negate?*/) {
3591 invalid_arithemetic_operation(processor, cia,
3592 frT, product, *frB, 0,
3593 0, /*instruction_is_frsp*/
3594 0, /*instruction_is_convert_to_64bit*/
3595 0, /*instruction_is_convert_to_32bit*/
3596 0); /*single-precision*/
3597 }
3598 else {
3599 /*HACK!*/
3600 double s = product + *(double*)frB;
3601 *(double*)frT = s;
3602 }
3603 FPSCR_END(Rc);
45525d8d 3604 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3605
c143ef62 36060.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
54e98699
MM
3607*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3608*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3609*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3610*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3611 FPSCR_BEGIN;
3612 float product; /*HACK! - incorrectly loosing precision ... */
3613 /* compute the multiply */
3614 if (is_invalid_operation(processor, cia,
3615 *frA, *frC,
3616 fpscr_vxsnan | fpscr_vximz,
3617 1, /*single?*/
3618 0) /*negate?*/) {
3619 invalid_arithemetic_operation(processor, cia,
3620 (unsigned64*)&product, *frA, 0, *frC,
3621 0, /*instruction_is_frsp*/
3622 0, /*instruction_is_convert_to_64bit*/
3623 0, /*instruction_is_convert_to_32bit*/
3624 0); /*single-precision*/
3625 }
3626 else {
3627 /*HACK!*/
3628 product = *(double*)frA * *(double*)frC;
3629 }
3630 /* compute the add */
3631 if (is_invalid_operation(processor, cia,
3632 product, *frB,
3633 fpscr_vxsnan | fpscr_vxisi,
3634 1, /*single?*/
3635 0) /*negate?*/) {
3636 invalid_arithemetic_operation(processor, cia,
3637 frT, product, *frB, 0,
3638 0, /*instruction_is_frsp*/
3639 0, /*instruction_is_convert_to_64bit*/
3640 0, /*instruction_is_convert_to_32bit*/
3641 0); /*single-precision*/
3642 }
3643 else {
3644 /*HACK!*/
3645 float s = product + *(double*)frB;
3646 *(double*)frT = (double)s;
3647 }
3648 FPSCR_END(Rc);
45525d8d 3649 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4a0351ab
MM
3650
36510.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3652*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3653*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3654*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
54e98699 3655*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3656 FPSCR_BEGIN;
3657 double product; /*HACK! - incorrectly loosing precision ... */
3658 /* compute the multiply */
3659 if (is_invalid_operation(processor, cia,
3660 *frA, *frC,
3661 fpscr_vxsnan | fpscr_vximz,
3662 0, /*single?*/
3663 0) /*negate?*/) {
3664 invalid_arithemetic_operation(processor, cia,
3665 (unsigned64*)&product, *frA, 0, *frC,
3666 0, /*instruction_is_frsp*/
3667 0, /*instruction_is_convert_to_64bit*/
3668 0, /*instruction_is_convert_to_32bit*/
3669 0); /*single-precision*/
3670 }
3671 else {
3672 /*HACK!*/
3673 product = *(double*)frA * *(double*)frC;
3674 }
3675 /* compute the subtract */
3676 if (is_invalid_operation(processor, cia,
3677 product, *frB,
3678 fpscr_vxsnan | fpscr_vxisi,
3679 0, /*single?*/
3680 0) /*negate?*/) {
3681 invalid_arithemetic_operation(processor, cia,
3682 frT, product, *frB, 0,
3683 0, /*instruction_is_frsp*/
3684 0, /*instruction_is_convert_to_64bit*/
3685 0, /*instruction_is_convert_to_32bit*/
3686 0); /*single-precision*/
3687 }
3688 else {
3689 /*HACK!*/
3690 double s = product - *(double*)frB;
3691 *(double*)frT = s;
3692 }
3693 FPSCR_END(Rc);
45525d8d 3694 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3695
c143ef62 36960.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
54e98699
MM
3697*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3698*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3699*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3700*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3701 FPSCR_BEGIN;
3702 float product; /*HACK! - incorrectly loosing precision ... */
3703 /* compute the multiply */
3704 if (is_invalid_operation(processor, cia,
3705 *frA, *frC,
3706 fpscr_vxsnan | fpscr_vximz,
3707 1, /*single?*/
3708 0) /*negate?*/) {
3709 invalid_arithemetic_operation(processor, cia,
3710 (unsigned64*)&product, *frA, 0, *frC,
3711 0, /*instruction_is_frsp*/
3712 0, /*instruction_is_convert_to_64bit*/
3713 0, /*instruction_is_convert_to_32bit*/
3714 0); /*single-precision*/
3715 }
3716 else {
3717 /*HACK!*/
3718 product = *(double*)frA * *(double*)frC;
3719 }
3720 /* compute the subtract */
3721 if (is_invalid_operation(processor, cia,
3722 product, *frB,
3723 fpscr_vxsnan | fpscr_vxisi,
3724 1, /*single?*/
3725 0) /*negate?*/) {
3726 invalid_arithemetic_operation(processor, cia,
3727 frT, product, *frB, 0,
3728 0, /*instruction_is_frsp*/
3729 0, /*instruction_is_convert_to_64bit*/
3730 0, /*instruction_is_convert_to_32bit*/
3731 0); /*single-precision*/
3732 }
3733 else {
3734 /*HACK!*/
3735 float s = product - *(double*)frB;
3736 *(double*)frT = (double)s;
3737 }
3738 FPSCR_END(Rc);
45525d8d 3739 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3740
37410.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
54e98699
MM
3742*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3743*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3744*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3745*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3746 FPSCR_BEGIN;
3747 double product; /*HACK! - incorrectly loosing precision ... */
3748 /* compute the multiply */
3749 if (is_invalid_operation(processor, cia,
3750 *frA, *frC,
3751 fpscr_vxsnan | fpscr_vximz,
3752 0, /*single?*/
3753 0) /*negate?*/) {
3754 invalid_arithemetic_operation(processor, cia,
3755 (unsigned64*)&product, *frA, 0, *frC,
3756 0, /*instruction_is_frsp*/
3757 0, /*instruction_is_convert_to_64bit*/
3758 0, /*instruction_is_convert_to_32bit*/
3759 0); /*single-precision*/
3760 }
3761 else {
3762 /*HACK!*/
3763 product = *(double*)frA * *(double*)frC;
3764 }
3765 /* compute the add */
3766 if (is_invalid_operation(processor, cia,
3767 product, *frB,
3768 fpscr_vxsnan | fpscr_vxisi,
3769 0, /*single?*/
3770 0) /*negate?*/) {
3771 invalid_arithemetic_operation(processor, cia,
3772 frT, product, *frB, 0,
3773 0, /*instruction_is_frsp*/
3774 0, /*instruction_is_convert_to_64bit*/
3775 0, /*instruction_is_convert_to_32bit*/
3776 0); /*single-precision*/
3777 }
3778 else {
3779 /*HACK!*/
3780 double s = -(product + *(double*)frB);
3781 *(double*)frT = s;
3782 }
3783 FPSCR_END(Rc);
45525d8d 3784 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3785
c143ef62 37860.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
54e98699
MM
3787*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3788*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3789*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3790*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3791 FPSCR_BEGIN;
3792 float product; /*HACK! - incorrectly loosing precision ... */
3793 /* compute the multiply */
3794 if (is_invalid_operation(processor, cia,
3795 *frA, *frC,
3796 fpscr_vxsnan | fpscr_vximz,
3797 1, /*single?*/
3798 0) /*negate?*/) {
3799 invalid_arithemetic_operation(processor, cia,
3800 (unsigned64*)&product, *frA, 0, *frC,
3801 0, /*instruction_is_frsp*/
3802 0, /*instruction_is_convert_to_64bit*/
3803 0, /*instruction_is_convert_to_32bit*/
3804 0); /*single-precision*/
3805 }
3806 else {
3807 /*HACK!*/
3808 product = *(double*)frA * *(double*)frC;
3809 }
3810 /* compute the add */
3811 if (is_invalid_operation(processor, cia,
3812 product, *frB,
3813 fpscr_vxsnan | fpscr_vxisi,
3814 1, /*single?*/
3815 0) /*negate?*/) {
3816 invalid_arithemetic_operation(processor, cia,
3817 frT, product, *frB, 0,
3818 0, /*instruction_is_frsp*/
3819 0, /*instruction_is_convert_to_64bit*/
3820 0, /*instruction_is_convert_to_32bit*/
3821 0); /*single-precision*/
3822 }
3823 else {
3824 /*HACK!*/
3825 float s = -(product + *(double*)frB);
3826 *(double*)frT = (double)s;
3827 }
3828 FPSCR_END(Rc);
45525d8d 3829 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3830
38310.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
54e98699
MM
3832*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3833*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3834*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3835*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3836 FPSCR_BEGIN;
3837 double product; /*HACK! - incorrectly loosing precision ... */
3838 /* compute the multiply */
3839 if (is_invalid_operation(processor, cia,
3840 *frA, *frC,
3841 fpscr_vxsnan | fpscr_vximz,
3842 0, /*single?*/
3843 0) /*negate?*/) {
3844 invalid_arithemetic_operation(processor, cia,
3845 (unsigned64*)&product, *frA, 0, *frC,
3846 0, /*instruction_is_frsp*/
3847 0, /*instruction_is_convert_to_64bit*/
3848 0, /*instruction_is_convert_to_32bit*/
3849 0); /*single-precision*/
3850 }
3851 else {
3852 /*HACK!*/
3853 product = *(double*)frA * *(double*)frC;
3854 }
3855 /* compute the subtract */
3856 if (is_invalid_operation(processor, cia,
3857 product, *frB,
3858 fpscr_vxsnan | fpscr_vxisi,
3859 0, /*single?*/
3860 0) /*negate?*/) {
3861 invalid_arithemetic_operation(processor, cia,
3862 frT, product, *frB, 0,
3863 0, /*instruction_is_frsp*/
3864 0, /*instruction_is_convert_to_64bit*/
3865 0, /*instruction_is_convert_to_32bit*/
3866 0); /*single-precision*/
3867 }
3868 else {
3869 /*HACK!*/
3870 double s = -(product - *(double*)frB);
3871 *(double*)frT = s;
3872 }
3873 FPSCR_END(Rc);
45525d8d 3874 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3875
c143ef62 38760.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
54e98699
MM
3877*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3878*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3879*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3880*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3881 FPSCR_BEGIN;
3882 float product; /*HACK! - incorrectly loosing precision ... */
3883 /* compute the multiply */
3884 if (is_invalid_operation(processor, cia,
3885 *frA, *frC,
3886 fpscr_vxsnan | fpscr_vximz,
3887 1, /*single?*/
3888 0) /*negate?*/) {
3889 invalid_arithemetic_operation(processor, cia,
3890 (unsigned64*)&product, *frA, 0, *frC,
3891 0, /*instruction_is_frsp*/
3892 0, /*instruction_is_convert_to_64bit*/
3893 0, /*instruction_is_convert_to_32bit*/
3894 0); /*single-precision*/
3895 }
3896 else {
3897 /*HACK!*/
3898 product = *(double*)frA * *(double*)frC;
3899 }
3900 /* compute the subtract */
3901 if (is_invalid_operation(processor, cia,
3902 product, *frB,
3903 fpscr_vxsnan | fpscr_vxisi,
3904 1, /*single?*/
3905 0) /*negate?*/) {
3906 invalid_arithemetic_operation(processor, cia,
3907 frT, product, *frB, 0,
3908 0, /*instruction_is_frsp*/
3909 0, /*instruction_is_convert_to_64bit*/
3910 0, /*instruction_is_convert_to_32bit*/
3911 0); /*single-precision*/
3912 }
3913 else {
3914 /*HACK!*/
3915 float s = -(product - *(double*)frB);
3916 *(double*)frT = (double)s;
3917 }
3918 FPSCR_END(Rc);
45525d8d 3919 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3920
3921
3922#
3923# I.4.6.6 Floating-Point Rounding and Conversion Instructions
3924#
3925
39260.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
54e98699
MM
3927*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3928*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3929*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3930*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3931 int sign;
3932 int exp;
3933 unsigned64 frac_grx;
3934 /* split off cases for what to do */
3935 if (EXTRACTED64(*frB, 1, 11) < 897
3936 && EXTRACTED64(*frB, 1, 63) > 0) {
3937 if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow;
3938 if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow;
3939 }
3940 if (EXTRACTED64(*frB, 1, 11) > 1150
3941 && EXTRACTED64(*frB, 1, 11) < 2047) {
3942 if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
3943 if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow;
3944 }
3945 if (EXTRACTED64(*frB, 1, 11) > 896
3946 && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand;
3947 if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand;
3948 if (EXTRACTED64(*frB, 1, 11) == 2047) {
3949 if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand;
3950 if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand;
3951 if (EXTRACTED64(*frB, 12, 12) == 0
3952 && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand;
3953 }
3954 /* handle them */
3955 Disabled_Exponent_Underflow:
3956 sign = EXTRACTED64(*frB, 0, 0);
3957 if (EXTRACTED64(*frB, 1, 11) == 0) {
3958 exp = -1022;
3959 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3960 }
3961 if (EXTRACTED64(*frB, 1, 11) > 0) {
3962 exp = EXTRACTED64(*frB, 1, 11) - 1023;
3963 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
3964 }
c143ef62
MM
3965 /* G|R|X == zero from above */
3966 while (exp < -126) {
3967 exp = exp - 1;
3968 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
3969 | MASKED64(frac_grx, 55, 55));
3970 }
3971 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
3972 Round_Single(processor, sign, &exp, &frac_grx);
3973 FPSCR_SET_XX(FPSCR & fpscr_fi);
3974 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
3975 *frT = INSERTED64(sign, 0, 0);
3976 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
3977 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
3978 }
3979 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
3980 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
3981 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
3982 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
3983 }
3984 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
3985 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
3986 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
3987 }
3988 /*Normalize_Operand:*/
3989 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
3990 exp = exp - 1;
3991 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
3992 }
3993 *frT = (INSERTED64(sign, 0, 0)
3994 | INSERTED64(exp + 1023, 1, 11)
3995 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
3996 }
3997 goto Done;
3998 Enabled_Exponent_Underflow:
3999 FPSCR_SET_UX(1);
4000 sign = EXTRACTED64(*frB, 0, 0);
4001 if (EXTRACTED64(*frB, 1, 11) == 0) {
4002 exp = -1022;
4003 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4004 }
4005 if (EXTRACTED64(*frB, 1, 11) > 0) {
4006 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4007 frac_grx = (BIT64(0) |
4008 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4009 }
4010 /*Normalize_Operand:*/
4011 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4012 exp = exp - 1;
4013 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4014 }
4015 Round_Single(processor, sign, &exp, &frac_grx);
4016 FPSCR_SET_XX(FPSCR & fpscr_fi);
4017 exp = exp + 192;
4018 *frT = (INSERTED64(sign, 0, 0)
4019 | INSERTED64(exp + 1023, 1, 11)
4020 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4021 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4022 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4023 goto Done;
4024 Disabled_Exponent_Overflow:
4025 FPSCR_SET_OX(1);
4026 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4027 if (EXTRACTED64(*frB, 0, 0) == 0) {
4028 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4029 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4030 }
4031 if (EXTRACTED64(*frB, 0, 0) == 1) {
4032 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4033 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4034 }
4035 }
4036 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4037 if (EXTRACTED64(*frB, 0, 0) == 0) {
4038 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4039 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4040 }
4041 if (EXTRACTED64(*frB, 0, 0) == 1) {
4042 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4043 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4044 }
4045 }
4046 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4047 if (EXTRACTED64(*frB, 0, 0) == 0) {
4048 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4049 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4050 }
4051 if (EXTRACTED64(*frB, 0, 0) == 1) {
4052 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4053 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4054 }
4055 }
4056 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4057 if (EXTRACTED64(*frB, 0, 0) == 0) {
4058 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4059 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4060 }
4061 if (EXTRACTED64(*frB, 0, 0) == 1) {
4062 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4063 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4064 }
4065 }
4066 /* FPSCR[FR] <- undefined */
4067 FPSCR_SET_FI(1);
4068 FPSCR_SET_XX(1);
4069 goto Done;
4070 Enabled_Exponent_Overflow:
4071 sign = EXTRACTED64(*frB, 0, 0);
4072 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4073 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4074 Round_Single(processor, sign, &exp, &frac_grx);
4075 FPSCR_SET_XX(FPSCR & fpscr_fi);
4076 Enabled_Overflow:
4077 FPSCR_SET_OX(1);
4078 exp = exp - 192;
4079 *frT = (INSERTED64(sign, 0, 0)
4080 | INSERTED64(exp + 1023, 1, 11)
4081 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4082 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4083 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4084 goto Done;
4085 Zero_Operand:
4086 *frT = *frB;
4087 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4088 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4089 FPSCR_SET_FR(0);
4090 FPSCR_SET_FI(0);
4091 goto Done;
4092 Infinity_Operand:
4093 *frT = *frB;
4094 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4095 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4096 FPSCR_SET_FR(0);
4097 FPSCR_SET_FI(0);
4098 goto Done;
4099 QNaN_Operand:
4100 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4101 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4102 FPSCR_SET_FR(0);
4103 FPSCR_SET_FI(0);
4104 goto Done;
4105 SNaN_Operand:
4106 FPSCR_OR_VX(fpscr_vxsnan);
4107 if ((FPSCR & fpscr_ve) == 0) {
4108 *frT = (MASKED64(*frB, 0, 11)
4109 | BIT64(12)
4110 | MASKED64(*frB, 13, 34));
4111 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4112 }
4113 FPSCR_SET_FR(0);
4114 FPSCR_SET_FI(0);
4115 goto Done;
4116 Normal_Operand:
4117 sign = EXTRACTED64(*frB, 0, 0);
4118 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4119 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4120 Round_Single(processor, sign, &exp, &frac_grx);
4121 FPSCR_SET_XX(FPSCR & fpscr_fi);
4122 if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow;
4123 if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow;
4124 *frT = (INSERTED64(sign, 0, 0)
4125 | INSERTED64(exp + 1023, 1, 11)
4126 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4127 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4128 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4129 goto Done;
4130 Done:
45525d8d 4131 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 4132
c143ef62 41330.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
845ff5a4 4134
c143ef62 41350.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
845ff5a4 4136
c143ef62 41370.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
845ff5a4 4138
c143ef62 41390.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
54e98699
MM
4140*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4141*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4142*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4143*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4144 FPSCR_BEGIN;
4145 convert_to_integer(processor, cia,
4146 frT, *frB,
4147 fpscr_rn_round_towards_zero, 32);
4148 FPSCR_END(Rc);
45525d8d 4149 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 4150
c143ef62
MM
41510.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4152 int sign = EXTRACTED64(*frB, 0, 0);
4153 int exp = 63;
4154 unsigned64 frac = *frB;
4155 if (frac == 0) goto Zero_Operand;
4156 if (sign == 1) frac = ~frac + 1;
4157 while (EXTRACTED64(frac, 0, 0) == 0) {
4158 /*??? do the loop 0 times if (FRB) = max negative integer */
4159 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4160 exp = exp - 1;
4161 }
4162 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4163 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4164 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4165 *frT = (INSERTED64(sign, 0, 0)
4166 | INSERTED64(exp + 1023, 1, 11)
4167 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4168 goto Done;
4169 /**/
4170 Zero_Operand:
4171 FPSCR_SET_FR(0);
4172 FPSCR_SET_FI(0);
4173 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4174 *frT = 0;
4175 goto Done;
4176 /**/
4177 Done:
45525d8d 4178 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
c143ef62
MM
4179
4180#
4181# I.4.6.7 Floating-Point Compare Instructions
4182#
4183
41840.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
54e98699
MM
4185*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4186*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4187*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4188*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4189 FPSCR_BEGIN;
4190 unsigned c;
4191 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4192 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4193 else if (is_less_than(frA, frB))
4194 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4195 else if (is_greater_than(frA, frB))
4196 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4197 else
4198 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4199 FPSCR_SET_FPCC(c);
4200 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4201 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4202 FPSCR_OR_VX(fpscr_vxsnan);
4203 FPSCR_END(0);
45525d8d 4204 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
845ff5a4 4205
c143ef62 42060.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
54e98699
MM
4207*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4208*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4209*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4210*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4211 FPSCR_BEGIN;
4212 unsigned c;
4213 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4214 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4215 else if (is_less_than(frA, frB))
4216 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4217 else if (is_greater_than(frA, frB))
4218 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4219 else
4220 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4221 FPSCR_SET_FPCC(c);
4222 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4223 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4224 FPSCR_OR_VX(fpscr_vxsnan);
4225 if ((FPSCR & fpscr_ve) == 0)
4226 FPSCR_OR_VX(fpscr_vxvc);
4227 }
4228 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4229 FPSCR_OR_VX(fpscr_vxvc);
4230 }
4231 FPSCR_END(0);
45525d8d 4232 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
c143ef62
MM
4233
4234
4235#
4236# I.4.6.8 Floating-Point Status and Control Register Instructions
4237#
4238
42390.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
845ff5a4 4240
c143ef62 42410.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
845ff5a4 4242
c143ef62 42430.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
845ff5a4 4244
c143ef62 42450.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
845ff5a4 4246
c143ef62 42470.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
845ff5a4 4248
c143ef62
MM
42490.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4250
4251
4252#
4253# I.A.1.1 Floating-Point Store Instruction
4254#
42550.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4256
4257#
4258# I.A.1.2 Floating-Point Arithmetic Instructions
4259#
4260
42610.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
845ff5a4 4262
c143ef62
MM
42630.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4264
42650.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
845ff5a4 4266
c143ef62
MM
42670.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4268
4269#
4270# I.A.1.3 Floating-Point Select Instruction
4271#
4272
42730.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4274
4275
4276#
4277# II.3.2 Cache Management Instructions
4278#
4279
42800.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
54e98699
MM
4281*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4282*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4283*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4284*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
80948f39
MM
4285 /* blindly flush all instruction cache entries */
4286 #if WITH_IDECODE_CACHE_SIZE
4287 cpu_flush_icache(processor);
4288 #endif
45525d8d 4289 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
4290
42910.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
54e98699
MM
4292*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4293*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4294*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4295*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
c143ef62 4296 cpu_synchronize_context(processor);
45525d8d 4297 PPC_INSN_INT(0, 0, 0);
c143ef62
MM
4298
4299
4300#
4301# II.3.2.2 Data Cache Instructions
4302#
4303
43040.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
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, 1, 0
845ff5a4 4309 TRACE(trace_tbd,("Data Cache Block Touch\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.246,31./:X:::Data Cache Block Touch for Store
54e98699
MM
4313*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4314*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4315*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4316*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
845ff5a4 4317 TRACE(trace_tbd,("Data Cache Block Touch for Store\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.1014,31./:X:::Data Cache Block set to Zero
54e98699
MM
4321*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4322*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4323*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4324*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
845ff5a4 4325 TRACE(trace_tbd,("Data Cache Block set to Zero\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.54,31./:X:::Data Cache Block Store
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 Store\n"));
45525d8d 4334 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
056e975c 4335
c143ef62 43360.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
54e98699
MM
4337*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4338*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4339*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4340*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
845ff5a4 4341 TRACE(trace_tbd,("Data Cache Block Flush\n"));
45525d8d 4342 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
c143ef62
MM
4343
4344#
845ff5a4 4345# II.3.3 Enforce In-order Execution of I/O Instruction
c143ef62
MM
4346#
4347
43480.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4349 /* Since this model has no instruction overlap
4350 this instruction need do nothing */
4351
4352#
4353# II.4.1 Time Base Instructions
4354#
4355
43560.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
54e98699
MM
4357*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4358*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4359*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62
MM
4360 int n = (tbr{5:9} << 5) | tbr{0:4};
4361 if (n == 268) {
4362 if (is_64bit_implementation) *rT = TB;
4363 else *rT = EXTRACTED64(TB, 32, 63);
4364 }
4365 else if (n == 269) {
4366 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4367 else *rT = EXTRACTED64(TB, 0, 31);
4368 }
4369 else
4370 program_interrupt(processor, cia,
4371 illegal_instruction_program_interrupt);
4372
4373
4374#
4375# III.2.3.1 System Linkage Instructions
4376#
4377
80948f39 43780.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
54e98699
MM
4379*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4380*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4381*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4382*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
80948f39
MM
4383 if (IS_PROBLEM_STATE(processor)) {
4384 program_interrupt(processor, cia,
4385 privileged_instruction_program_interrupt);
4386 }
4387 else {
4388 MSR = (MASKED(SRR1, 0, 32)
4389 | MASKED(SRR1, 37, 41)
4390 | MASKED(SRR1, 48, 63));
4391 NIA = MASKED(SRR0, 0, 61);
4392 cpu_synchronize_context(processor);
4393 }
c143ef62
MM
4394
4395#
4396# III.3.4.1 Move to/from System Register Instructions
4397#
4398
f2181eff
MM
4399#0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4400#0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
c143ef62 44010.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
54e98699
MM
4402*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4403*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4404*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4405*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4406 if (IS_PROBLEM_STATE(processor))
4407 program_interrupt(processor, cia,
4408 privileged_instruction_program_interrupt);
4409 else
4410 MSR = *rS;
845ff5a4 4411
c143ef62 44120.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
54e98699
MM
4413*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4414*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4415*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4416*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62
MM
4417 if (IS_PROBLEM_STATE(processor))
4418 program_interrupt(processor, cia,
4419 privileged_instruction_program_interrupt);
4420 else
4421 *rT = MSR;
4422
4423
4424#
4425# III.4.11.1 Cache Management Instructions
4426#
4427
44280.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
54e98699
MM
4429*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4430*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4431*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4432*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
845ff5a4
MM
4433 if (IS_PROBLEM_STATE(processor))
4434 program_interrupt(processor, cia,
4435 privileged_instruction_program_interrupt);
4436 else
4437 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
c143ef62
MM
4438
4439#
4440# III.4.11.2 Segment Register Manipulation Instructions
4441#
4442
44430.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
54e98699
MM
4444*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4445*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4446*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4447*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4448 if (IS_PROBLEM_STATE(processor))
4449 program_interrupt(processor, cia,
4450 privileged_instruction_program_interrupt);
4451 else
4452 SEGREG(SR) = *rS;
845ff5a4 4453
c143ef62 44540.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
54e98699
MM
4455*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4456*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4457*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4458*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4459 if (IS_PROBLEM_STATE(processor))
4460 program_interrupt(processor, cia,
4461 privileged_instruction_program_interrupt);
4462 else
4463 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
845ff5a4 4464
c143ef62 44650.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
54e98699
MM
4466*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4467*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4468*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4469*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4470 if (IS_PROBLEM_STATE(processor))
4471 program_interrupt(processor, cia,
4472 privileged_instruction_program_interrupt);
4473 else
4474 *rT = SEGREG(SR);
845ff5a4 4475
c143ef62 44760.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
54e98699
MM
4477*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4478*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4479*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4480*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4481 if (IS_PROBLEM_STATE(processor))
4482 program_interrupt(processor, cia,
4483 privileged_instruction_program_interrupt);
4484 else
4485 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4486
4487
4488#
4489# III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4490#
4491
44920.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
845ff5a4 4493
c143ef62
MM
44940.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4495
44960.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
845ff5a4 4497
c143ef62
MM
44980.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
4499
45000.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize
4501
4502
4503#
4504# III.A.1.2 External Access Instructions
4505#
4506
45070.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
845ff5a4 4508
c143ef62 45090.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
This page took 0.622104 seconds and 4 git commands to generate.