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