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