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