New revision from Andrew
[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);
30c87b55
MM
1112 enum { start, finish, Infinity_Operand, SNaN_Operand, QNaN_Operand, Large_Operand, Done } label = start;
1113 while (label != finish) switch (label) {
1114 case finish:
1115 error("Unhandled switch\n");
1116 case start:
1117 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0)
1118 { label = Infinity_Operand; break; }
1119 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0)
1120 { label = SNaN_Operand; break; }
1121 if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1)
1122 { label = QNaN_Operand; break; }
1123 if (EXTRACTED64(frb, 1, 11) > 1086) { label = Large_Operand; break; }
1124 if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023;
1125 if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022;
1126 if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */
1127 frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1128 frac64 = 0;
1129 }
1130 if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */
1131 frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53);
1132 frac64 = 0;
1133 }
1134 gbit = 0, rbit = 0, xbit = 0;
1135 for (i = 1; i <= 63 - exp; i++) {
1136 xbit = rbit | xbit;
1137 rbit = gbit;
1138 gbit = frac64;
1139 frac64 = EXTRACTED64(frac, 63, 63);
1140 frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63);
1141 }
1142 Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode);
1143 if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */
1144 frac = ~frac;
1145 frac64 ^= 1;
1146 frac += (frac64 ? 1 : 0);
1147 frac64 = (frac64 + 1) & 0x1;
1148 }
1149 if (tgt_precision == 32 /* can ignore frac64 in compare */
1150 && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/)
1151 { label = Large_Operand; break; }
1152 if (tgt_precision == 64 /* can ignore frac64 in compare */
1153 && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/)
1154 { label = Large_Operand; break; }
1155 if (tgt_precision == 32 /* can ignore frac64 in compare */
1156 && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/)
1157 { label = Large_Operand; break; }
1158 if (tgt_precision == 64 /* can ignore frac64 in compare */
1159 && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/)
1160 { label = Large_Operand; break; }
1161 FPSCR_SET_XX(FPSCR & fpscr_fi);
1162 if (tgt_precision == 32)
1163 *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64;
1164 if (tgt_precision == 64)
1165 *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64;
1166 /*FPSCR[fprf] = undefined */
1167 { label = Done; break; }
1168 /**/
1169 case Infinity_Operand:
c143ef62
MM
1170 FPSCR_SET_FR(0);
1171 FPSCR_SET_FI(0);
1172 FPSCR_OR_VX(fpscr_vxcvi);
1173 if ((FPSCR & fpscr_ve) == 0) {
1174 if (tgt_precision == 32) {
1175 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF;
1176 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1177 }
1178 else {
1179 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1180 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1181 }
1182 /* FPSCR[FPRF] = undefined */
1183 }
30c87b55 1184 { label = Done; break; }
c143ef62 1185 /**/
30c87b55 1186 case SNaN_Operand:
c143ef62
MM
1187 FPSCR_SET_FR(0);
1188 FPSCR_SET_FI(0);
1189 FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi);
1190 if ((FPSCR & fpscr_ve) == 0) {
1191 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1192 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1193 /* FPSCR[fprf] = undefined */
1194 }
30c87b55 1195 { label = Done; break; }
c143ef62 1196 /**/
30c87b55 1197 case QNaN_Operand:
c143ef62
MM
1198 FPSCR_SET_FR(0);
1199 FPSCR_SET_FI(0);
1200 FPSCR_OR_VX(fpscr_vxcvi);
1201 if ((FPSCR & fpscr_ve) == 0) {
1202 if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1203 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/
1204 /* FPSCR[fprf] = undefined */
1205 }
30c87b55 1206 { label = Done; break; }
c143ef62 1207 /**/
30c87b55 1208 case Large_Operand:
c143ef62
MM
1209 FPSCR_SET_FR(0);
1210 FPSCR_SET_FI(0);
1211 FPSCR_OR_VX(fpscr_vxcvi);
1212 if ((FPSCR & fpscr_ve) == 0) {
1213 if (tgt_precision == 32) {
1214 if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff;
1215 if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000;
1216 }
1217 else {
1218 if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/
1219 if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/
1220 }
1221 /* FPSCR[fprf] = undefined */
1222 }
1223 /**/
30c87b55
MM
1224 case Done:
1225 { label = finish; break; }
1226 }
c143ef62
MM
1227
1228
1229# extract out raw fields of a FP number
1230int::function::sign:unsigned64 FRS
1231 return (MASKED64(FRS, 0, 0)
1232 ? -1
1233 : 1);
1234int::function::biased_exp:unsigned64 frs, int single
1235 if (single)
1236 return EXTRACTED64(frs, 1, 8);
1237 else
1238 return EXTRACTED64(frs, 1, 11);
1239unsigned64::function::fraction:unsigned64 frs, int single
1240 if (single)
1241 return EXTRACTED64(frs, 9, 31);
1242 else
1243 return EXTRACTED64(frs, 12, 63);
1244
1245# a number?, each of the below return +1 or -1 (based on sign bit)
1246# if true.
1247int::function::is_nor:unsigned64 frs, int single
1248 int exp = biased_exp(frs, single);
1249 return (exp >= 1
1250 && exp <= (single ? 254 : 2046));
1251int::function::is_zero:unsigned64 FRS
1252 return (MASKED64(FRS, 1, 63) == 0
1253 ? sign(FRS)
1254 : 0);
1255int::function::is_den:unsigned64 frs, int single
1256 int exp = biased_exp(frs, single);
1257 unsigned64 frac = fraction(frs, single);
1258 return (exp == 0 && frac != 0
1259 ? sign(frs)
1260 : 0);
1261int::function::is_inf: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_NaN:unsigned64 frs, int single
1268 int exp = biased_exp(frs, single);
1269 int frac = fraction(frs, single);
1270 return (exp == (single ? 255 : 2047) && frac != 0
1271 ? sign(frs)
1272 : 0);
1273int::function::is_SNaN:unsigned64 frs, int single
1274 return (is_NaN(frs, single)
1275 && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12)))
1276 ? sign(frs)
1277 : 0);
1278int::function::is_QNaN:unsigned64 frs, int single
1279 return (is_NaN(frs, single) && !is_SNaN(frs, single));
1280int::function::is_less_than:unsigned64 *fra, unsigned64 *frb
1281 return *(double*)fra < *(double*)frb;
1282int::function::is_greater_than:unsigned64 *fra, unsigned64 *frb
1283 return *(double*)fra > *(double*)frb;
1284int::function::is_equan_to:unsigned64 *fra, unsigned64 *frb
1285 return *(double*)fra == *(double*)frb;
845ff5a4 1286
c143ef62
MM
1287
1288# which quiet nan should become the result
1289unsigned64::function::select_qnan:unsigned64 fra, unsigned64 frb, unsigned64 frc, int instruction_is_frsp, int generate_qnan, int single
1290 unsigned64 frt = 0;
1291 if (is_NaN(fra, single))
1292 frt = fra;
1293 else if (is_NaN(frb, single))
1294 if (instruction_is_frsp)
1295 frt = MASKED64(frb, 0, 34);
1296 else
1297 frt = frb;
1298 else if (is_NaN(frc, single))
1299 frt = frc;
1300 else if (generate_qnan)
1301 frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */
1302 else
1303 error("select_qnan - default reached\n");
1304 return frt;
845ff5a4 1305
c143ef62
MM
1306
1307# detect invalid operation
1308int::function::is_invalid_operation:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, fpscreg check, int single, int negate
1309 int fail = 0;
1310 if ((check & fpscr_vxsnan)
1311 && (is_SNaN(fra, single) || is_SNaN(frb, single))) {
1312 FPSCR_OR_VX(fpscr_vxsnan);
1313 fail = 1;
1314 }
1315 if ((check & fpscr_vxisi)
1316 && (is_inf(fra, single) && is_inf(frb, single))
1317 && ((negate && sign(fra) != sign(frb))
1318 || (!negate && sign(fra) == sign(frb)))) {
1319 /*FIXME: don't handle inf-inf VS inf+-inf */
1320 FPSCR_OR_VX(fpscr_vxisi);
1321 fail = 1;
1322 }
1323 if ((check & fpscr_vxidi)
1324 && (is_inf(fra, single) && is_inf(frb, single))) {
1325 FPSCR_OR_VX(fpscr_vxidi);
1326 fail = 1;
1327 }
1328 if ((check & fpscr_vxzdz)
1329 && (is_zero(fra) && is_zero(frb))) {
1330 FPSCR_OR_VX(fpscr_vxzdz);
1331 fail = 1;
1332 }
1333 if ((check & fpscr_vximz)
1334 && (is_zero(fra) && is_inf(frb, single))) {
1335 FPSCR_OR_VX(fpscr_vximz);
1336 fail = 1;
1337 }
1338 if ((check & fpscr_vxvc)
1339 && (is_NaN(fra, single) || is_NaN(frb, single))) {
1340 FPSCR_OR_VX(fpscr_vxvc);
1341 fail = 1;
1342 }
1343 if ((check & fpscr_vxsoft)) {
1344 FPSCR_OR_VX(fpscr_vxsoft);
1345 fail = 1;
1346 }
1347 if ((check & fpscr_vxsqrt)
1348 && sign(fra) < 0) {
1349 FPSCR_OR_VX(fpscr_vxsqrt);
1350 fail = 1;
1351 }
1352 /* if ((check && fpscr_vxcvi) {
1353 && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single)))
1354 FPSCR_OR_VX(fpscr_vxcvi);
1355 fail = 1;
1356 }
1357 */
1358 return fail;
1359
1360
845ff5a4 1361
c143ef62
MM
1362
1363
1364# handle case of invalid operation
1365void::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
1366 if (FPSCR & fpscr_ve) {
1367 /* invalid operation exception enabled */
1368 /* FRT unchaged */
1369 FPSCR_SET_FR(0);
1370 FPSCR_SET_FI(0);
1371 /* fpscr_FPRF unchanged */
1372 }
1373 else {
1374 /* invalid operation exception disabled */
1375 if (instruction_is_convert_to_64bit) {
1376 error("oopsi");
1377 }
1378 else if (instruction_is_convert_to_32bit) {
1379 error("oopsi");
1380 }
1381 else { /* arrith, frsp */
1382 *frt = select_qnan(fra, frb, frc,
1383 instruction_is_frsp, 0/*generate*/, single);
1384 FPSCR_SET_FR(0);
1385 FPSCR_SET_FI(0);
1386 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
1387 }
1388 }
1389
1390
1391
1392
4ffd6ed0
MM
1393#
1394# 0.0.0.0 Illegal instruction used for kernel mode emulation
1395#
13960.0,6./,11./,16./,21./,31.1:X:::instruction_call
1397 if (!os_emul_instruction_call(processor, cia, real_addr(cia, 1)))
1398 program_interrupt(processor, cia,
1399 illegal_instruction_program_interrupt);
1400
c143ef62
MM
1401#
1402# I.2.4.1 Branch Instructions
1403#
30c87b55 14040.18,6.LI,30.AA,31.LK:I:::Branch
54e98699
MM
1405*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1406*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1407*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1408*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62
MM
1409 if (AA) NIA = IEA(EXTS(LI_0b00));
1410 else NIA = IEA(CIA + EXTS(LI_0b00));
1411 if (LK) LR = (spreg)CIA+4;
290ad14a 1412 if (CURRENT_MODEL_ISSUE > 0)
3d2f9d7c 1413 model_branches(cpu_model(processor), 1, -1);
84bbbc35 1414
30c87b55 14150.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:::Branch Conditional
54e98699
MM
1416*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1417*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1418*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1419*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
84bbbc35 1420 int M, ctr_ok, cond_ok, succeed;
290ad14a 1421 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
54e98699 1422 model_wait_for_cr(cpu_model(processor), BIT32_BI);
c143ef62
MM
1423 if (is_64bit_implementation && is_64bit_mode) M = 0;
1424 else M = 32;
1425 if (!BO{2}) CTR = CTR - 1;
1426 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
1427 cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
84bbbc35 1428 if (ctr_ok && cond_ok) {
c143ef62
MM
1429 if (AA) NIA = IEA(EXTS(BD_0b00));
1430 else NIA = IEA(CIA + EXTS(BD_0b00));
84bbbc35
MM
1431 succeed = 1;
1432 }
1433 else
1434 succeed = 0;
c143ef62 1435 if (LK) LR = (spreg)IEA(CIA + 4);
290ad14a 1436 if (CURRENT_MODEL_ISSUE > 0)
3d2f9d7c 1437 model_branches(cpu_model(processor), succeed, BO);
84bbbc35
MM
1438 if (! BO{0}) {
1439 int reverse;
1440 if (BO{4}) { /* branch prediction bit set, reverse sense of test */
1441 reverse = EXTS(BD_0b00) < 0;
1442 } else { /* branch prediction bit not set */
1443 reverse = EXTS(BD_0b00) >= 0;
1444 }
290ad14a 1445 if (CURRENT_MODEL_ISSUE > 0)
3d2f9d7c 1446 model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
84bbbc35
MM
1447 }
1448
30c87b55 14490.19,6.BO,11.BI,16./,21.16,31.LK:XL:::Branch Conditional to Link Register
54e98699
MM
1450*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1451*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1452*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1453*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
84bbbc35 1454 int M, ctr_ok, cond_ok, succeed;
c143ef62
MM
1455 if (is_64bit_implementation && is_64bit_mode) M = 0;
1456 else M = 32;
290ad14a 1457 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
54e98699 1458 model_wait_for_cr(cpu_model(processor), BIT32_BI);
c143ef62
MM
1459 if (!BO{2}) CTR = CTR - 1;
1460 ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
1461 cond_ok = BO{0} || (CR{BI} == BO{1});
84bbbc35
MM
1462 if (ctr_ok && cond_ok) {
1463 NIA = IEA(LR_0b00);
1464 succeed = 1;
1465 }
1466 else
1467 succeed = 0;
c143ef62 1468 if (LK) LR = (spreg)IEA(CIA + 4);
290ad14a 1469 if (CURRENT_MODEL_ISSUE > 0) {
3d2f9d7c
MM
1470 model_branches(cpu_model(processor), succeed, BO);
1471 if (! BO{0})
1472 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1473 }
84bbbc35 1474
30c87b55 14750.19,6.BO,11.BI,16./,21.528,31.LK:XL:::Branch Conditional to Count Register
54e98699
MM
1476*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1477*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1478*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
1479*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
84bbbc35 1480 int cond_ok, succeed;
290ad14a 1481 if (CURRENT_MODEL_ISSUE > 0 && ! BO{0})
54e98699 1482 model_wait_for_cr(cpu_model(processor), BIT32_BI);
c143ef62 1483 cond_ok = BO{0} || (CR{BI} == BO{1});
84bbbc35
MM
1484 if (cond_ok) {
1485 NIA = IEA(CTR_0b00);
1486 succeed = 1;
1487 }
1488 else
1489 succeed = 0;
c143ef62 1490 if (LK) LR = (spreg)IEA(CIA + 4);
290ad14a 1491 if (CURRENT_MODEL_ISSUE > 0) {
3d2f9d7c
MM
1492 model_branches(cpu_model(processor), succeed, BO);
1493 if (! BO{0})
1494 model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
1495 }
c143ef62
MM
1496
1497#
1498# I.2.4.2 System Call Instruction
1499#
30c87b55 15000.17,6./,11./,16./,30.1,31./:SC:::System Call
54e98699
MM
1501*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1502*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1503*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
1504*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
290ad14a 1505 if (CURRENT_MODEL_ISSUE > 0)
30c87b55 1506 model_serialize(MY_INDEX, cpu_model(processor));
c143ef62
MM
1507 system_call_interrupt(processor, cia);
1508
1509#
1510# I.2.4.3 Condition Register Logical Instructions
1511#
15120.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND
54e98699
MM
1513*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1514*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1515*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1516*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1517 BLIT32(CR, BT, CR{BA} && CR{BB});
f2181eff 1518 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
845ff5a4 1519
c143ef62 15200.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
54e98699
MM
1521*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1522*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1523*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1524*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1525 BLIT32(CR, BT, CR{BA} || CR{BB});
f2181eff 1526 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
845ff5a4 1527
c143ef62 15280.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
54e98699
MM
1529*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1530*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1531*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1532*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1533 BLIT32(CR, BT, CR{BA} != CR{BB});
f2181eff 1534 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
845ff5a4 1535
c143ef62 15360.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
54e98699
MM
1537*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1538*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1539*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1540*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1541 BLIT32(CR, BT, !(CR{BA} && CR{BB}));
f2181eff 1542 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
845ff5a4 1543
c143ef62 15440.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
54e98699
MM
1545*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1546*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1547*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1548*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1549 BLIT32(CR, BT, !(CR{BA} || CR{BB}));
f2181eff 1550 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
845ff5a4 1551
c143ef62 15520.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
54e98699
MM
1553*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1554*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1555*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1556*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1557 BLIT32(CR, BT, CR{BA} == CR{BB});
f2181eff 1558 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
845ff5a4 1559
c143ef62 15600.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
54e98699
MM
1561*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1562*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1563*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1564*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1565 BLIT32(CR, BT, CR{BA} && !CR{BB});
f2181eff 1566 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
845ff5a4 1567
c143ef62 15680.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
54e98699
MM
1569*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1570*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1571*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1572*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1573 BLIT32(CR, BT, CR{BA} || !CR{BB});
f2181eff 1574 PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
c143ef62
MM
1575
1576#
1577# I.2.4.4 Condition Register Field Instruction
1578#
15790.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field
54e98699
MM
1580*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1581*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1582*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
1583*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
c143ef62 1584 MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
f2181eff 1585 PPC_INSN_CR(BF_BITMASK, 1 << BFA);
c143ef62
MM
1586
1587
1588#
1589# I.3.3.2 Fixed-Point Load Instructions
1590#
1591
15920.34,6.RT,11.RA,16.D:D:::Load Byte and Zero
54e98699
MM
1593*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1594*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1595*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1596*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1597 unsigned_word b;
1598 unsigned_word EA;
1599 if (RA == 0) b = 0;
1600 else b = *rA;
1601 EA = b + EXTS(D);
1602 *rT = MEM(unsigned, EA, 1);
45525d8d 1603 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
54e98699 1604
845ff5a4 1605
c143ef62 16060.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed
54e98699
MM
1607*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1608*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1609*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1610*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1611 unsigned_word b;
1612 unsigned_word EA;
1613 if (RA == 0) b = 0;
1614 else b = *rA;
1615 EA = b + *rB;
1616 *rT = MEM(unsigned, EA, 1);
45525d8d 1617 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 1618
c143ef62 16190.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update
54e98699
MM
1620*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1621*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1622*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1623*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1624 unsigned_word EA;
1625 if (RA == 0 || RA == RT)
1626 program_interrupt(processor, cia,
1627 illegal_instruction_program_interrupt);
1628 EA = *rA + EXTS(D);
1629 *rT = MEM(unsigned, EA, 1);
1630 *rA = EA;
45525d8d 1631 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1632
c143ef62 16330.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed
54e98699
MM
1634*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1635*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1636*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1637*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1638 unsigned_word EA;
1639 if (RA == 0 || RA == RT)
1640 program_interrupt(processor, cia,
1641 illegal_instruction_program_interrupt);
1642 EA = *rA + *rB;
1643 *rT = MEM(unsigned, EA, 1);
1644 *rA = EA;
45525d8d 1645 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1646
16470.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero
54e98699
MM
1648*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1649*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1650*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1651*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1652 unsigned_word b;
1653 unsigned_word EA;
1654 if (RA == 0) b = 0;
1655 else b = *rA;
1656 EA = b + EXTS(D);
1657 *rT = MEM(unsigned, EA, 2);
45525d8d 1658 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 1659
c143ef62 16600.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed
54e98699
MM
1661*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1662*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1663*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1664*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1665 unsigned_word b;
1666 unsigned_word EA;
1667 if (RA == 0) b = 0;
1668 else b = *rA;
1669 EA = b + *rB;
1670 *rT = MEM(unsigned, EA, 2);
45525d8d 1671 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
54e98699 1672
c143ef62 16730.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update
54e98699
MM
1674*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1675*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1676*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1677*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1678 unsigned_word EA;
1679 if (RA == 0 || RA == RT)
1680 program_interrupt(processor, cia,
1681 illegal_instruction_program_interrupt);
1682 EA = *rA + EXTS(D);
1683 *rT = MEM(unsigned, EA, 2);
1684 *rA = EA;
45525d8d 1685 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1686
c143ef62 16870.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed
54e98699
MM
1688*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1689*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1690*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1691*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1692 unsigned_word EA;
1693 if (RA == 0 || RA == RT)
1694 program_interrupt(processor, cia,
1695 illegal_instruction_program_interrupt);
1696 EA = *rA + *rB;
1697 *rT = MEM(unsigned, EA, 2);
1698 *rA = EA;
45525d8d 1699 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1700
17010.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic
54e98699
MM
1702*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1703*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1704*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1705*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1706 unsigned_word b;
1707 unsigned_word EA;
1708 if (RA == 0) b = 0;
1709 else b = *rA;
1710 EA = b + EXTS(D);
1711 *rT = MEM(signed, EA, 2);
45525d8d 1712 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 1713
c143ef62 17140.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed
54e98699
MM
1715*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1716*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1717*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1718*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1719 unsigned_word b;
1720 unsigned_word EA;
1721 if (RA == 0) b = 0;
1722 else b = *rA;
1723 EA = b + *rB;
1724 *rT = MEM(signed, EA, 2);
45525d8d 1725 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 1726
c143ef62 17270.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update
54e98699
MM
1728*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1729*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1730*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1731*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1732 unsigned_word EA;
1733 if (RA == 0 || RA == RT)
1734 program_interrupt(processor, cia,
1735 illegal_instruction_program_interrupt);
1736 EA = *rA + EXTS(D);
1737 *rT = MEM(signed, EA, 2);
45525d8d 1738 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1739
c143ef62 17400.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed
54e98699
MM
1741*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1742*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1743*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1744*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1745 unsigned_word EA;
1746 if (RA == 0 || RA == RT)
1747 program_interrupt(processor, cia,
1748 illegal_instruction_program_interrupt);
1749 EA = *rA + *rB;
1750 *rT = MEM(signed, EA, 2);
1751 *rA = EA;
45525d8d 1752 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1753
17540.32,6.RT,11.RA,16.D:D:::Load Word and Zero
54e98699
MM
1755*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1756*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1757*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1758*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1759 unsigned_word b;
1760 unsigned_word EA;
1761 if (RA == 0) b = 0;
1762 else b = *rA;
1763 EA = b + EXTS(D);
1764 *rT = MEM(unsigned, EA, 4);
45525d8d 1765 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 1766
c143ef62 17670.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed
54e98699
MM
1768*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1769*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1770*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1771*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1772 unsigned_word b;
1773 unsigned_word EA;
1774 if (RA == 0) b = 0;
1775 else b = *rA;
1776 EA = b + *rB;
1777 *rT = MEM(unsigned, EA, 4);
45525d8d 1778 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 1779
c143ef62 17800.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update
54e98699
MM
1781*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1782*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1783*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1784*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1785 unsigned_word EA;
1786 if (RA == 0 || RA == RT)
1787 program_interrupt(processor, cia,
1788 illegal_instruction_program_interrupt);
1789 EA = *rA + EXTS(D);
1790 *rT = MEM(unsigned, EA, 4);
1791 *rA = EA;
45525d8d 1792 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0);
845ff5a4 1793
c143ef62 17940.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed
54e98699
MM
1795*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0
1796*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1797*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1798*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
c143ef62
MM
1799 unsigned_word EA;
1800 if (RA == 0 || RA == RT)
1801 program_interrupt(processor, cia,
1802 illegal_instruction_program_interrupt);
1803 EA = *rA + *rB;
1804 *rT = MEM(unsigned, EA, 4);
1805 *rA = EA;
45525d8d 1806 PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0);
c143ef62
MM
1807
18080.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic
1809# unsigned_word b;
1810# unsigned_word EA;
1811# if (RA == 0) b = 0;
1812# else b = *rA;
1813# EA = b + EXTS(DS_0b00);
1814# *rT = MEM(signed, EA, 4);
845ff5a4 1815
c143ef62
MM
18160.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed
1817# unsigned_word b;
1818# unsigned_word EA;
1819# if (RA == 0) b = 0;
1820# else b = *rA;
1821# EA = b + *rB;;
1822# *rT = MEM(signed, EA, 4);
845ff5a4 1823
c143ef62
MM
18240.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed
1825# unsigned_word EA;
1826# if (RA == 0 || RA == RT)
1827# program_interrupt(processor, cia
1828# illegal_instruction_program_interrupt);
1829# EA = *rA + *rB;
1830# *rT = MEM(signed, EA, 4);
1831# *rA = EA;
1832
18330.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword
1834# unsigned_word b;
1835# unsigned_word EA;
1836# if (RA == 0) b = 0;
1837# else b = *rA;
1838# EA = b + EXTS(DS_0b00);
1839# *rT = MEM(unsigned, EA, 8);
845ff5a4 1840
c143ef62
MM
18410.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed
1842# unsigned_word b;
1843# unsigned_word EA;
1844# if (RA == 0) b = 0;
1845# else b = *rA;
1846# EA = b + *rB;
1847# *rT = MEM(unsigned, EA, 8);
845ff5a4 1848
c143ef62
MM
18490.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update
1850# unsigned_word EA;
1851# if (RA == 0 || RA == RT)
1852# program_interrupt(processor, cia
1853# illegal_instruction_program_interrupt);
1854# EA = *rA + EXTS(DS_0b00);
1855# *rT = MEM(unsigned, EA, 8);
1856# *rA = EA;
845ff5a4 1857
c143ef62
MM
18580.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed
1859# unsigned_word EA;
1860# if (RA == 0 || RA == RT)
1861# program_interrupt(processor, cia
1862# illegal_instruction_program_interrupt);
1863# EA = *rA + *rB;
1864# *rT = MEM(unsigned, EA, 8);
1865# *rA = EA;
1866
1867
1868
1869#
1870# I.3.3.3 Fixed-Point Store Instructions
1871#
1872
18730.38,6.RS,11.RA,16.D:D:::Store Byte
54e98699
MM
1874*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1875*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1876*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1877*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1878 unsigned_word b;
1879 unsigned_word EA;
1880 if (RA == 0) b = 0;
1881 else b = *rA;
1882 EA = b + EXTS(D);
1883 STORE(EA, 1, *rS);
45525d8d 1884 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
845ff5a4 1885
c143ef62 18860.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed
54e98699
MM
1887*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1888*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1889*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1890*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1891 unsigned_word b;
1892 unsigned_word EA;
1893 if (RA == 0) b = 0;
1894 else b = *rA;
1895 EA = b + *rB;
1896 STORE(EA, 1, *rS);
45525d8d 1897 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 1898
c143ef62 18990.39,6.RS,11.RA,16.D:D:::Store Byte with Update
54e98699
MM
1900*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1901*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1902*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1903*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1904 unsigned_word EA;
1905 if (RA == 0)
1906 program_interrupt(processor, cia,
1907 illegal_instruction_program_interrupt);
1908 EA = *rA + EXTS(D);
1909 STORE(EA, 1, *rS);
1910 *rA = EA;
45525d8d 1911 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
845ff5a4 1912
c143ef62 19130.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed
54e98699
MM
1914*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1915*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1916*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1917*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1918 unsigned_word EA;
1919 if (RA == 0)
1920 program_interrupt(processor, cia,
1921 illegal_instruction_program_interrupt);
1922 EA = *rA + *rB;
1923 STORE(EA, 1, *rS);
1924 *rA = EA;
45525d8d 1925 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
1926
19270.44,6.RS,11.RA,16.D:D:::Store Half Word
54e98699
MM
1928*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1929*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1930*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1931*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1932 unsigned_word b;
1933 unsigned_word EA;
1934 if (RA == 0) b = 0;
1935 else b = *rA;
1936 EA = b + EXTS(D);
1937 STORE(EA, 2, *rS);
45525d8d 1938 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
845ff5a4 1939
c143ef62 19400.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed
54e98699
MM
1941*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1942*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1943*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1944*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1945 unsigned_word b;
1946 unsigned_word EA;
1947 if (RA == 0) b = 0;
1948 else b = *rA;
1949 EA = b + *rB;
1950 STORE(EA, 2, *rS);
45525d8d 1951 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 1952
c143ef62 19530.45,6.RS,11.RA,16.D:D:::Store Half Word with Update
54e98699
MM
1954*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1955*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1956*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1957*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1958 unsigned_word EA;
1959 if (RA == 0)
1960 program_interrupt(processor, cia,
1961 illegal_instruction_program_interrupt);
1962 EA = *rA + EXTS(D);
1963 STORE(EA, 2, *rS);
1964 *rA = EA;
45525d8d 1965 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
845ff5a4 1966
c143ef62 19670.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed
54e98699
MM
1968*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1969*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1970*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1971*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1972 unsigned_word EA;
1973 if (RA == 0)
1974 program_interrupt(processor, cia,
1975 illegal_instruction_program_interrupt);
1976 EA = *rA + *rB;
1977 STORE(EA, 2, *rS);
1978 *rA = EA;
45525d8d 1979 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
1980
19810.36,6.RS,11.RA,16.D:D:::Store Word
54e98699
MM
1982*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1983*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1984*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1985*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1986 unsigned_word b;
1987 unsigned_word EA;
1988 if (RA == 0) b = 0;
1989 else b = *rA;
1990 EA = b + EXTS(D);
1991 STORE(EA, 4, *rS);
45525d8d 1992 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0);
845ff5a4 1993
c143ef62 19940.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed
54e98699
MM
1995*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
1996*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1997*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
1998*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
1999 unsigned_word b;
2000 unsigned_word EA;
2001 if (RA == 0) b = 0;
2002 else b = *rA;
2003 EA = b + *rB;
2004 STORE(EA, 4, *rS);
45525d8d 2005 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 2006
c143ef62 20070.37,6.RS,11.RA,16.D:D:::Store Word with Update
54e98699
MM
2008*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2009*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2010*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2011*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
2012 unsigned_word EA;
2013 if (RA == 0)
2014 program_interrupt(processor, cia,
2015 illegal_instruction_program_interrupt);
2016 EA = *rA + EXTS(D);
2017 STORE(EA, 4, *rS);
2018 *rA = EA;
45525d8d 2019 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0);
845ff5a4 2020
c143ef62 20210.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed
54e98699
MM
2022*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2023*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2024*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2025*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
2026 unsigned_word EA;
2027 if (RA == 0)
2028 program_interrupt(processor, cia,
2029 illegal_instruction_program_interrupt);
2030 EA = *rA + *rB;
2031 STORE(EA, 4, *rS);
2032 *rA = EA;
45525d8d 2033 PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
2034
20350.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword
2036# unsigned_word b;
2037# unsigned_word EA;
2038# if (RA == 0) b = 0;
2039# else b = *rA;
2040# EA = b + EXTS(DS_0b00);
2041# STORE(EA, 8, *rS);
20420.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed
2043# unsigned_word b;
2044# unsigned_word EA;
2045# if (RA == 0) b = 0;
2046# else b = *rA;
2047# EA = b + *rB;
2048# STORE(EA, 8, *rS);
20490.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update
2050# unsigned_word EA;
2051# if (RA == 0)
2052# program_interrupt(processor, cia
2053# illegal_instruction_program_interrupt);
2054# EA = *rA + EXTS(DS_0b00);
2055# STORE(EA, 8, *rS);
2056# *rA = EA;
20570.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed
2058# unsigned_word EA;
2059# if (RA == 0)
2060# program_interrupt(processor, cia
2061# illegal_instruction_program_interrupt);
2062# EA = *rA + *rB;
2063# STORE(EA, 8, *rS);
2064# *rA = EA;
2065
2066
2067#
2068# I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions
2069#
2070
20710.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
54e98699
MM
2072*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2073*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2074*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2075*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2076 unsigned_word b;
2077 unsigned_word EA;
2078 if (RA == 0) b = 0;
2079 else b = *rA;
2080 EA = b + *rB;
2081 *rT = SWAP_2(MEM(unsigned, EA, 2));
45525d8d 2082 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 2083
c143ef62 20840.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
54e98699
MM
2085*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2086*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2087*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2088*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2089 unsigned_word b;
2090 unsigned_word EA;
2091 if (RA == 0) b = 0;
2092 else b = *rA;
2093 EA = b + *rB;
2094 *rT = SWAP_4(MEM(unsigned, EA, 4));
45525d8d 2095 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
2096
20970.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
54e98699
MM
2098*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2099*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2100*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2101*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2102 unsigned_word b;
2103 unsigned_word EA;
2104 if (RA == 0) b = 0;
2105 else b = *rA;
2106 EA = b + *rB;
2107 STORE(EA, 2, SWAP_2(*rS));
45525d8d 2108 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
845ff5a4 2109
c143ef62 21100.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
54e98699
MM
2111*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2112*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2113*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
2114*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
73c4941b
MM
2115 unsigned_word b;
2116 unsigned_word EA;
2117 if (RA == 0) b = 0;
2118 else b = *rA;
2119 EA = b + *rB;
2120 STORE(EA, 4, SWAP_4(*rS));
45525d8d 2121 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0);
c143ef62
MM
2122
2123
2124#
2125# I.3.3.5 Fixed-Point Load and Store Multiple Instrctions
2126#
2127
30c87b55 21280.46,6.RT,11.RA,16.D:D:::Load Multiple Word
845ff5a4 2129
30c87b55 21300.47,6.RS,11.RA,16.D:D:::Store Multiple Word
c143ef62
MM
2131
2132
2133#
2134# I.3.3.6 Fixed-Point Move Assist Instructions
2135#
2136
30c87b55 21370.31,6.RT,11.RA,16.NB,21.597,31./:X:::Load String Word Immediate
845ff5a4 2138
30c87b55 21390.31,6.RT,11.RA,16.RB,21.533,31./:X:::Load String Word Indexed
c143ef62 2140
30c87b55 21410.31,6.RS,11.RA,16.NB,21.725,31./:X:::Store String Word Immedate
845ff5a4 2142
30c87b55 21430.31,6.RS,11.RA,16.RB,21.661,31./:X:::Store String Word Indexed
c143ef62
MM
2144
2145
2146#
2147# I.3.3.7 Storage Synchronization Instructions
2148#
2149# HACK: Rather than monitor addresses looking for a reason
2150# to cancel a reservation. This code instead keeps
2151# a copy of the data read from memory. Before performing
2152# a store, the memory area is checked to see if it has
2153# been changed.
21540.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed
54e98699
MM
2155*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2156*603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2157*603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0
2158*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
2159 unsigned_word b;
2160 unsigned_word EA;
2161 if (RA == 0) b = 0;
2162 else b = *rA;
2163 EA = b + *rB;
2164 RESERVE = 1;
2165 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2166 RESERVE_DATA = MEM(unsigned, EA, 4);
2167 *rT = RESERVE_DATA;
45525d8d 2168 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 2169
c143ef62
MM
21700.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed
2171 unsigned_word b;
2172 unsigned_word EA;
2173 if (RA == 0) b = 0;
2174 else b = *rA;
2175 EA = b + *rB;
2176 RESERVE = 1;
2177 RESERVE_ADDR = real_addr(EA, 1/*is-read?*/);
2178 RESERVE_DATA = MEM(unsigned, EA, 8);
2179 *rT = RESERVE_DATA;
45525d8d 2180 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
2181
21820.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed
54e98699
MM
2183*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2184*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2185*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0
2186*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0
c143ef62
MM
2187 unsigned_word b;
2188 unsigned_word EA;
2189 if (RA == 0) b = 0;
2190 else b = *rA;
2191 EA = b + *rB;
2192 if (RESERVE) {
2193 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2194 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) {
2195 STORE(EA, 4, *rS);
2196 CR_SET_XER_SO(0, cr_i_zero);
2197 }
2198 else {
2199 /* ment to randomly to store, we never do! */
2200 CR_SET_XER_SO(0, 0);
2201 }
2202 RESERVE = 0;
2203 }
2204 else {
2205 CR_SET_XER_SO(0, 0);
2206 }
45525d8d
MM
2207 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
2208
c143ef62
MM
22090.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed
2210 unsigned_word b;
2211 unsigned_word EA;
2212 if (RA == 0) b = 0;
2213 else b = *rA;
2214 EA = b + *rB;
2215 if (RESERVE) {
2216 if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/)
2217 && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) {
2218 STORE(EA, 8, *rS);
2219 CR_SET_XER_SO(0, cr_i_zero);
2220 }
2221 else {
2222 /* ment to randomly to store, we never do */
2223 CR_SET_XER_SO(0, 0);
2224 }
2225 RESERVE = 0;
2226 }
2227 else {
2228 CR_SET_XER_SO(0, 0);
2229 }
45525d8d 2230 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/);
c143ef62
MM
2231
22320.31,6./,11./,16./,21.598,31./:X::sync:Synchronize
54e98699
MM
2233*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2234*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2235*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
2236*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
c143ef62
MM
2237 /* do nothing */
2238
2239
2240#
2241# I.3.3.9 Fixed-Point Arithmetic Instructions
2242#
2243
30c87b55 22440.14,6.RT,11.RA,16.SI:D:::Add Immediate
54e98699
MM
2245*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2246*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2247*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2248*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
45525d8d
MM
2249 if (RA_is_0) *rT = EXTS(SI);
2250 else *rT = *rA + EXTS(SI);
4ffd6ed0 2251 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
45525d8d 2252 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
80948f39 2253
c143ef62 22540.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted
54e98699
MM
2255*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2256*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2257*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2258*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
45525d8d
MM
2259 if (RA_is_0) *rT = EXTS(SI) << 16;
2260 else *rT = *rA + (EXTS(SI) << 16);
4ffd6ed0 2261 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT));
45525d8d 2262 PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0);
80948f39 2263
c143ef62 22640.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add
54e98699
MM
2265*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2266*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2267*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2268*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2269 ALU_BEGIN(*rA);
2270 ALU_ADD(*rB);
2271 ALU_END(*rT, 0/*CA*/, OE, Rc);
45525d8d 2272 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2273
c143ef62 22740.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From
54e98699
MM
2275*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2276*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2277*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2278*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2279 ALU_BEGIN(*rA);
2280 ALU_NOT;
2281 ALU_ADD(*rB);
2282 ALU_ADD(1);
2283 ALU_END(*rT, 0/*CA*/, OE, Rc);
45525d8d 2284 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2285
c143ef62 22860.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying
54e98699
MM
2287*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2288*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2289*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2290*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2291 ALU_BEGIN(*rA);
2292 ALU_ADD(EXTS(SI));
2293 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
45525d8d 2294 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
80948f39 2295
c143ef62 22960.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record
54e98699
MM
2297*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2298*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2299*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2300*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2301 ALU_BEGIN(*rA);
2302 ALU_ADD(EXTS(SI));
2303 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/);
45525d8d 2304 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/);
80948f39 2305
c143ef62 23060.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying
54e98699
MM
2307*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2308*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2309*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2310*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2311 ALU_BEGIN(*rA);
2312 ALU_NOT;
2313 ALU_ADD(EXTS(SI));
2314 ALU_ADD(1);
2315 ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/);
45525d8d 2316 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
80948f39 2317
c143ef62 23180.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying
54e98699
MM
2319*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2320*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2321*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2322*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2323 ALU_BEGIN(*rA);
2324 ALU_ADD(*rB);
2325 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2326 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2327
c143ef62 23280.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying
54e98699
MM
2329*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2330*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2331*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2332*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2333 /* RT <- ~RA + RB + 1 === RT <- RB - RA */
2334 ALU_BEGIN(*rA);
2335 ALU_NOT;
2336 ALU_ADD(*rB);
2337 ALU_ADD(1);
2338 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2339 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2340
c143ef62 23410.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended
54e98699
MM
2342*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2343*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2344*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2345*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2346 ALU_BEGIN(*rA);
2347 ALU_ADD(*rB);
2348 ALU_ADD_CA;
2349 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2350 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2351
c143ef62 23520.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended
54e98699
MM
2353*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2354*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2355*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2356*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2357 ALU_BEGIN(*rA);
2358 ALU_NOT;
2359 ALU_ADD(*rB);
2360 ALU_ADD_CA;
2361 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2362 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2363
c143ef62 23640.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended
54e98699
MM
2365*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2366*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2367*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2368*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
4ffd6ed0
MM
2369 ALU_BEGIN(*rA);
2370 ALU_ADD_CA;
2371 ALU_ADD(-1);
2372 ALU_END(*rT, 1/*CA*/, OE, Rc);
2373 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2374
c143ef62 23750.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended
54e98699
MM
2376*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2377*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2378*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2379*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
4ffd6ed0
MM
2380 ALU_BEGIN(*rA);
2381 ALU_NOT;
2382 ALU_ADD_CA;
2383 ALU_ADD(-1);
2384 ALU_END(*rT, 1/*CA*/, OE, Rc);
2385 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2386
c143ef62 23870.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended
54e98699
MM
2388*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2389*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2390*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2391*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2392 ALU_BEGIN(*rA);
2393 ALU_ADD_CA;
2394 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2395 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2396
c143ef62 23970.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended
54e98699
MM
2398*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2399*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2400*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2401*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2402 ALU_BEGIN(*rA);
2403 ALU_NOT;
2404 ALU_ADD_CA;
2405 ALU_END(*rT, 1/*CA*/, OE, Rc);
45525d8d 2406 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2407
c143ef62 24080.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate
54e98699
MM
2409*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2410*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2411*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2412*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2413 ALU_BEGIN(*rA);
2414 ALU_NOT;
2415 ALU_ADD(1);
2416 ALU_END(*rT,0/*CA*/,OE,Rc);
45525d8d 2417 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc);
80948f39 2418
c143ef62 24190.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate
54e98699
MM
2420*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2421*603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2422*603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
2423*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62
MM
2424 signed_word prod = *rA * EXTS(SI);
2425 *rT = prod;
45525d8d 2426 PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/);
80948f39 2427
c143ef62 24280.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword
80948f39 2429
c143ef62 24300.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word
54e98699
MM
2431*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2432*603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2433*603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2434*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
c143ef62
MM
2435 signed64 a = (signed32)(*rA);
2436 signed64 b = (signed32)(*rB);
2437 signed64 prod = a * b;
2438 signed_word t = prod;
2439 *rT = *rA * *rB;
2440 if (t != prod && OE)
2441 XER |= (xer_overflow | xer_summary_overflow);
2442 CR0_COMPARE(t, 0, Rc);
45525d8d 2443 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2444
c143ef62 24450.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword
80948f39 2446
c143ef62 24470.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word
54e98699
MM
2448*601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2449*603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2450*603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0
2451*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
c143ef62
MM
2452 signed64 a = (signed32)(*rA);
2453 signed64 b = (signed32)(*rB);
2454 signed64 prod = a * b;
2455 signed_word t = EXTRACTED64(prod, 0, 31);
2456 *rT = t;
2457 CR0_COMPARE(t, 0, Rc);
45525d8d 2458 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2459
c143ef62 24600.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned
80948f39 2461
c143ef62 24620.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::milhwu:Multiply High Word Unsigned
54e98699
MM
2463*601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0
2464*603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2465*603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0
2466*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0
c143ef62
MM
2467 unsigned64 a = (unsigned32)(*rA);
2468 unsigned64 b = (unsigned32)(*rB);
2469 unsigned64 prod = a * b;
2470 signed_word t = EXTRACTED64(prod, 0, 31);
2471 *rT = t;
2472 CR0_COMPARE(t, 0, Rc);
45525d8d 2473 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
80948f39 2474
c143ef62 24750.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword
80948f39 2476
c143ef62 24770.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word
54e98699
MM
2478*601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2479*603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2480*603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2481*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
c143ef62
MM
2482 signed64 dividend = (signed32)(*rA);
2483 signed64 divisor = (signed32)(*rB);
2484 if (divisor == 0 /* nb 0x8000..0 is sign extended */
2485 || (dividend == 0x80000000 && divisor == -1)) {
2486 if (OE)
2487 XER |= (xer_overflow | xer_summary_overflow);
2488 CR0_COMPARE(0, 0, Rc);
2489 }
2490 else {
2491 signed64 quotent = dividend / divisor;
2492 *rT = quotent;
2493 CR0_COMPARE((signed_word)quotent, 0, Rc);
2494 }
45525d8d 2495 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
54e98699 2496
c143ef62 24970.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned
80948f39 2498
c143ef62 24990.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned
54e98699
MM
2500*601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0
2501*603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2502*603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0
2503*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0
c143ef62
MM
2504 unsigned64 dividend = (unsigned32)(*rA);
2505 unsigned64 divisor = (unsigned32)(*rB);
2506 if (divisor == 0) {
2507 if (OE)
2508 XER |= (xer_overflow | xer_summary_overflow);
2509 CR0_COMPARE(0, 0, Rc);
2510 }
2511 else {
2512 unsigned64 quotent = dividend / divisor;
2513 *rT = quotent;
2514 CR0_COMPARE((signed_word)quotent, 0, Rc);
2515 }
45525d8d 2516 PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc);
c143ef62
MM
2517
2518
2519#
2520# I.3.3.10 Fixed-Point Compare Instructions
2521#
2522
25230.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate
54e98699
MM
2524*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2525*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2526*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2527*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2528 if (!is_64bit_mode && L)
2529 program_interrupt(processor, cia,
2530 illegal_instruction_program_interrupt);
2531 else {
2532 signed_word a;
2533 signed_word b = EXTS(SI);
2534 if (L == 0)
2535 a = EXTENDED(*rA);
2536 else
2537 a = *rA;
2538 CR_COMPARE(BF, a, b);
2539 }
45525d8d 2540 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
845ff5a4 2541
c143ef62 25420.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare
54e98699
MM
2543*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2544*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2545*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2546*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2547 if (!is_64bit_mode && L)
2548 program_interrupt(processor, cia,
2549 illegal_instruction_program_interrupt);
2550 else {
2551 signed_word a;
2552 signed_word b;
2553 if (L == 0) {
2554 a = EXTENDED(*rA);
2555 b = EXTENDED(*rB);
2556 }
2557 else {
2558 a = *rA;
2559 b = *rB;
2560 }
2561 CR_COMPARE(BF, a, b);
2562 }
45525d8d 2563 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
845ff5a4 2564
c143ef62 25650.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate
54e98699
MM
2566*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2567*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2568*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2569*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2570 if (!is_64bit_mode && L)
2571 program_interrupt(processor, cia,
2572 illegal_instruction_program_interrupt);
2573 else {
2574 unsigned_word a;
2575 unsigned_word b = UI;
2576 if (L == 0)
2577 a = MASKED(*rA, 32, 63);
2578 else
2579 a = *rA;
2580 CR_COMPARE(BF, a, b);
2581 }
45525d8d 2582 PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK);
845ff5a4 2583
c143ef62 25840.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical
54e98699
MM
2585*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2586*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2587*603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0
2588*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2589 if (!is_64bit_mode && L)
2590 program_interrupt(processor, cia,
2591 illegal_instruction_program_interrupt);
2592 else {
2593 unsigned_word a;
2594 unsigned_word b;
2595 if (L == 0) {
2596 a = MASKED(*rA, 32, 63);
2597 b = MASKED(*rB, 32, 63);
2598 }
2599 else {
2600 a = *rA;
2601 b = *rB;
2602 }
2603 CR_COMPARE(BF, a, b);
2604 }
45525d8d 2605 PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK);
c143ef62
MM
2606
2607
2608#
2609# I.3.3.11 Fixed-Point Trap Instructions
2610#
2611
26120.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate
2613 if (!is_64bit_mode)
2614 program_interrupt(processor, cia,
2615 illegal_instruction_program_interrupt);
2616 else {
2617 signed_word a = *rA;
2618 signed_word b = EXTS(SI);
2619 if ((a < b && TO{0})
2620 || (a > b && TO{1})
2621 || (a == b && TO{2})
2622 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2623 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2624 )
2625 program_interrupt(processor, cia,
2626 trap_program_interrupt);
2627 }
845ff5a4 2628
c143ef62 26290.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate
54e98699
MM
2630*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2631*603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2632*603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2633*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2634 signed_word a = EXTENDED(*rA);
2635 signed_word b = EXTS(SI);
2636 if ((a < b && TO{0})
2637 || (a > b && TO{1})
2638 || (a == b && TO{2})
2639 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2640 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2641 )
2642 program_interrupt(processor, cia,
2643 trap_program_interrupt);
845ff5a4 2644
c143ef62
MM
26450.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword
2646 if (!is_64bit_mode)
2647 program_interrupt(processor, cia,
2648 illegal_instruction_program_interrupt);
2649 else {
2650 signed_word a = *rA;
2651 signed_word b = *rB;
2652 if ((a < b && TO{0})
2653 || (a > b && TO{1})
2654 || (a == b && TO{2})
2655 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2656 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2657 )
2658 program_interrupt(processor, cia,
2659 trap_program_interrupt);
2660 }
845ff5a4 2661
c143ef62 26620.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word
54e98699
MM
2663*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2664*603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2665*603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
2666*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2667 signed_word a = EXTENDED(*rA);
2668 signed_word b = EXTENDED(*rB);
2669 if (TO == 12 && rA == rB) {
2670 ITRACE(trace_breakpoint, ("breakpoint\n"));
2671 cpu_halt(processor, cia, was_trap, 0);
2672 }
2673 else if ((a < b && TO{0})
2674 || (a > b && TO{1})
2675 || (a == b && TO{2})
2676 || ((unsigned_word)a < (unsigned_word)b && TO{3})
2677 || ((unsigned_word)a > (unsigned_word)b && TO{4})
2678 )
2679 program_interrupt(processor, cia,
2680 trap_program_interrupt);
2681
2682#
2683# I.3.3.12 Fixed-Point Logical Instructions
2684#
2685
26860.28,6.RS,11.RA,16.UI:D:::AND Immediate
54e98699
MM
2687*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2688*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2689*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2690*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2691 *rA = *rS & UI;
2692 CR0_COMPARE(*rA, 0, 1/*Rc*/);
4ffd6ed0 2693 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2694 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
845ff5a4 2695
c143ef62 26960.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted
54e98699
MM
2697*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2698*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2699*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2700*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2701 *rA = *rS & (UI << 16);
2702 CR0_COMPARE(*rA, 0, 1/*Rc*/);
4ffd6ed0 2703 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2704 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/);
845ff5a4 2705
c143ef62 27060.24,6.RS,11.RA,16.UI:D:::OR Immediate
54e98699
MM
2707*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2708*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2709*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2710*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62 2711 *rA = *rS | UI;
4ffd6ed0 2712 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2713 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2714
c143ef62 27150.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted
54e98699
MM
2716*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2717*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2718*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2719*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62 2720 *rA = *rS | (UI << 16);
4ffd6ed0 2721 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2722 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2723
c143ef62 27240.26,6.RS,11.RA,16.UI:D:::XOR Immediate
54e98699
MM
2725*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2726*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2727*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2728*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62 2729 *rA = *rS ^ UI;
4ffd6ed0 2730 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2731 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2732
c143ef62 27330.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted
54e98699
MM
2734*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2735*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2736*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2737*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62 2738 *rA = *rS ^ (UI << 16);
4ffd6ed0 2739 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2740 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/);
845ff5a4 2741
c143ef62 27420.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND
54e98699
MM
2743*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2744*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2745*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2746*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2747 *rA = *rS & *rB;
2748 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2749 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2750 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2751
c143ef62 27520.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR
54e98699
MM
2753*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2754*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2755*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2756*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2757 *rA = *rS | *rB;
2758 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2759 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2760 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2761
c143ef62 27620.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR
54e98699
MM
2763*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2764*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2765*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2766*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2767 *rA = *rS ^ *rB;
2768 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2769 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2770 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2771
c143ef62 27720.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND
54e98699
MM
2773*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2774*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2775*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2776*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2777 *rA = ~(*rS & *rB);
2778 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2779 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2780 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2781
c143ef62 27820.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR
54e98699
MM
2783*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2784*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2785*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2786*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2787 *rA = ~(*rS | *rB);
2788 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2789 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2790 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2791
c143ef62 27920.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent
54e98699
MM
2793*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2794*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2795*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2796*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
4ffd6ed0
MM
2797 *rA = ~(*rS ^ *rB); /* A === B */
2798 CR0_COMPARE(*rA, 0, Rc);
2799 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
2800 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2801
c143ef62 28020.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement
54e98699
MM
2803*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2804*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2805*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2806*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2807 *rA = *rS & ~*rB;
2808 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2809 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2810 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
54e98699 2811
c143ef62 28120.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement
54e98699
MM
2813*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2814*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2815*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2816*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2817 *rA = *rS | ~*rB;
2818 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2819 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2820 PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc);
845ff5a4 2821
c143ef62 28220.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte
54e98699
MM
2823*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2824*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2825*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2826*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2827 *rA = (signed_word)(signed8)*rS;
2828 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2829 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2830 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 2831
c143ef62 28320.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word
54e98699
MM
2833*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2834*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2835*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2836*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2837 *rA = (signed_word)(signed16)*rS;
2838 CR0_COMPARE(*rA, 0, Rc);
4ffd6ed0 2839 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
45525d8d 2840 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 2841
c143ef62 28420.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word
54e98699
MM
2843*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2844*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2845*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2846*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2847# *rA = (signed_word)(signed32)*rS;
2848# CR0_COMPARE(*rA, 0, Rc);
845ff5a4 2849
c143ef62
MM
28500.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword
2851# int count = 0;
2852# unsigned64 mask = BIT64(0);
2853# unsigned64 source = *rS;
2854# while (!(source & mask) && mask != 0) {
2855# mask >>= 1;
2856# count++;
2857# }
2858# *rA = count;
2859# CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
845ff5a4 2860
c143ef62 28610.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word
54e98699
MM
2862*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2863*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2864*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2865*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2866 int count = 0;
2867 unsigned32 mask = BIT32(0);
2868 unsigned32 source = *rS;
2869 while (!(source & mask) && mask != 0) {
2870 mask >>= 1;
2871 count++;
2872 }
2873 *rA = count;
4ffd6ed0 2874 ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
c143ef62
MM
2875 CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */
2876
2877
2878#
2879# I.3.3.13 Fixed-Point Rotate and Shift Instructions
2880#
2881
28820.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
2883# long n = (sh_5 << 4) | sh_0_4;
2884# unsigned_word r = ROTL64(*rS, n);
2885# long b = (mb_5 << 4) | mb_0_4;
2886# unsigned_word m = MASK(b, 63);
2887# signed_word result = r & m;
2888# *rA = result;
4ffd6ed0 2889# ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA));
c143ef62 2890# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
845ff5a4 2891
c143ef62
MM
28920.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
2893# long n = (sh_5 << 4) | sh_0_4;
2894# unsigned_word r = ROTL64(*rS, n);
2895# long e = (me_5 << 4) | me_0_4;
2896# unsigned_word m = MASK(0, e);
2897# signed_word result = r & m;
2898# *rA = result;
2899# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
845ff5a4 2900
c143ef62
MM
29010.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
2902# long n = (sh_5 << 4) | sh_0_4;
2903# unsigned_word r = ROTL64(*rS, n);
2904# long b = (mb_5 << 4) | mb_0_4;
2905# unsigned_word m = MASK(0, (64-n));
2906# signed_word result = r & m;
2907# *rA = result;
2908# CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */
2909
29100.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask
54e98699
MM
2911*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2912*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2913*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2914*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2915 long n = SH;
2916 unsigned32 s = *rS;
2917 unsigned32 r = ROTL32(s, n);
2918 unsigned32 m = MASK(MB+32, ME+32);
2919 signed_word result = r & m;
2920 *rA = result;
2921 CR0_COMPARE(result, 0, Rc);
2922 ITRACE(trace_alu,
45525d8d
MM
2923 ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n",
2924 n, (unsigned long)s, (unsigned long)r, (unsigned long)m,
2925 (unsigned long)result, (unsigned long)CR));
2926 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
2927
29280.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left
2929# long n = MASKED(*rB, 58, 63);
2930# unsigned_word r = ROTL64(*rS, n);
2931# long b = (mb_5 << 4) | mb_0_4;
2932# unsigned_word m = MASK(b, 63);
2933# signed_word result = r & m;
2934# *rA = result;
2935# CR0_COMPARE(result, 0, Rc);
845ff5a4 2936
c143ef62
MM
29370.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right
2938# long n = MASKED(*rB, 58, 63);
2939# unsigned_word r = ROTL64(*rS, n);
2940# long e = (me_5 << 4) | me_0_4;
2941# unsigned_word m = MASK(0, e);
2942# signed_word result = r & m;
2943# *rA = result;
2944# CR0_COMPARE(result, 0, Rc);
2945
29460.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask
2947# long n = MASKED(*rB, 59, 63);
2948# unsigned32 r = ROTL32(*rS, n);
2949# unsigned32 m = MASK(MB+32, ME+32);
2950# signed_word result = r & m;
2951# *rA = result;
2952# CR0_COMPARE(result, 0, Rc);
845ff5a4 2953
c143ef62
MM
29540.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
2955# long n = (sh_5 << 4) | sh_0_4;
2956# unsigned_word r = ROTL64(*rS, n);
2957# long b = (mb_5 << 4) | mb_0_4;
2958# unsigned_word m = MASK(b, (64-n));
2959# signed_word result = (r & m) | (*rA & ~m)
2960# *rA = result;
2961# CR0_COMPARE(result, 0, Rc);
845ff5a4 2962
c143ef62 29630.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert
54e98699
MM
2964*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2965*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2966*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2967*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2968 long n = SH;
2969 unsigned32 r = ROTL32(*rS, n);
2970 unsigned32 m = MASK(MB+32, ME+32);
2971 signed_word result = (r & m) | (*rA & ~m);
2972 *rA = result;
45525d8d
MM
2973 ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n",
2974 n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m,
2975 (unsigned long)result));
c143ef62 2976 CR0_COMPARE(result, 0, Rc);
45525d8d 2977 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
2978
2979
29800.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword
845ff5a4 2981
c143ef62 29820.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word
54e98699
MM
2983*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2984*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2985*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
2986*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
2987 int n = MASKED(*rB, 59, 63);
2988 unsigned32 source = *rS;
2989 signed_word shifted;
2990 if (n < 32)
2991 shifted = (source << n);
2992 else
2993 shifted = 0;
2994 *rA = shifted;
2995 CR0_COMPARE(shifted, 0, Rc);
2996 ITRACE(trace_alu,
45525d8d
MM
2997 ("n=%d, source=0x%lx, shifted=0x%lx\n",
2998 n, (unsigned long)source, (unsigned long)shifted));
2999 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 3000
c143ef62 30010.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword
845ff5a4 3002
c143ef62 30030.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word
54e98699
MM
3004*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3005*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3006*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3007*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
3008 int n = MASKED(*rB, 59, 63);
3009 unsigned32 source = *rS;
3010 signed_word shifted;
3011 if (n < 32)
3012 shifted = (source >> n);
3013 else
3014 shifted = 0;
3015 *rA = shifted;
3016 CR0_COMPARE(shifted, 0, Rc);
3017 ITRACE(trace_alu, \
45525d8d
MM
3018 ("n=%d, source=0x%lx, shifted=0x%lx\n",
3019 n, (unsigned long)source, (unsigned long)shifted));
3020 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
3021
30220.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate
845ff5a4 3023
c143ef62 30240.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate
54e98699
MM
3025*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3026*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3027*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3028*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
3029 int n = SH;
3030 signed_word r = ROTL32(*rS, /*64*/32-n);
3031 signed_word m = MASK(n+32, 63);
3032 int S = MASKED(*rS, 32, 32);
3033 signed_word shifted = (r & m) | (S ? ~m : 0);
3034 *rA = shifted;
3035 if (S && ((r & ~m) & MASK(32, 63)) != 0)
3036 XER |= xer_carry;
3037 else
3038 XER &= ~xer_carry;
3039 CR0_COMPARE(shifted, 0, Rc);
4ffd6ed0
MM
3040 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3041 (long)*rA, (long)*rA, (long)XER));
45525d8d 3042 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
845ff5a4 3043
c143ef62 30440.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword
845ff5a4 3045
c143ef62 30460.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word
54e98699
MM
3047*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3048*603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3049*603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3050*604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0
c143ef62
MM
3051 int n = MASKED(*rB, 58, 63);
3052 int shift = (n >= 31 ? 31 : n);
3053 signed32 source = (signed32)*rS; /* signed to keep sign bit */
3054 signed32 shifted = source >> shift;
3055 unsigned32 mask = ((unsigned32)-1) >> (31-shift);
3056 *rA = (signed_word)shifted; /* if 64bit will sign extend */
3057 if (source < 0 && (source & mask))
3058 XER |= xer_carry;
3059 else
3060 XER &= ~xer_carry;
3061 CR0_COMPARE(shifted, 0, Rc);
4ffd6ed0
MM
3062 ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n",
3063 (long)*rA, (long)*rA, (long)XER));
45525d8d 3064 PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc);
c143ef62
MM
3065
3066#
3067# I.3.3.14 Move to/from System Register Instructions
3068#
3069
f2181eff 30700.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
54e98699
MM
3071*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3072*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3073*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
3074*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
f2181eff
MM
3075 int n = (SPR{5:9} << 5) | SPR{0:4};
3076 if (SPR{0} && IS_PROBLEM_STATE(processor))
c143ef62
MM
3077 program_interrupt(processor, cia,
3078 privileged_instruction_program_interrupt);
3079 else if (!spr_is_valid(n)
3080 || spr_is_readonly(n))
3081 program_interrupt(processor, cia,
3082 illegal_instruction_program_interrupt);
3083 else {
3084 spreg new_val = (spr_length(n) == 64
3085 ? *rS
3086 : MASKED(*rS, 32, 63));
3087 /* HACK - time base registers need to be updated immediatly */
3088 if (WITH_TIME_BASE) {
c143ef62
MM
3089 switch (n) {
3090 case spr_tbu:
3091 cpu_set_time_base(processor,
80948f39
MM
3092 (MASKED64(cpu_get_time_base(processor), 32, 63)
3093 | INSERTED64(new_val, 0, 31)));
c143ef62
MM
3094 break;
3095 case spr_tbl:
3096 cpu_set_time_base(processor,
80948f39
MM
3097 (MASKED64(cpu_get_time_base(processor), 0, 31)
3098 | INSERTED64(new_val, 32, 63)));
c143ef62
MM
3099 break;
3100 case spr_dec:
3101 cpu_set_decrementer(processor, new_val);
3102 break;
3103 default:
3104 SPREG(n) = new_val;
3105 break;
3106 }
3107 }
3108 else {
3109 SPREG(n) = new_val;
3110 }
3111 }
45525d8d 3112 PPC_INSN_TO_SPR(RS_BITMASK, n);
845ff5a4 3113
f2181eff 31140.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
54e98699
MM
3115*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3116*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3117*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3118*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
f2181eff
MM
3119 int n = (SPR{5:9} << 5) | SPR{0:4};
3120 if (SPR{0} && IS_PROBLEM_STATE(processor))
c143ef62
MM
3121 program_interrupt(processor, cia,
3122 privileged_instruction_program_interrupt);
3123 else if (!spr_is_valid(n))
3124 program_interrupt(processor, cia,
3125 illegal_instruction_program_interrupt);
3126 else {
3127 /* HACK - some SPR's need to get their value extracted specially */
3128 *rT = SPREG(n);
3129 }
45525d8d 3130 PPC_INSN_FROM_SPR(RT_BITMASK, n);
845ff5a4 3131
c143ef62 31320.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields
54e98699
MM
3133*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
3134*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3135*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3136*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
3137 if (FXM == 0xff) {
3138 CR = *rS;
3139 }
3140 else {
3141 unsigned_word mask = 0;
3142 unsigned_word f;
3143 for (f = 0; f < 8; f++) {
3144 if (FXM & (0x80 >> f))
3145 mask |= (0xf << 4*(7-f));
3146 }
3147 CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
3148 }
f2181eff 3149 PPC_INSN_MTCR(RS_BITMASK, FXM);
845ff5a4 3150
c143ef62 31510.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
845ff5a4 3152
c143ef62 31530.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register
54e98699
MM
3154*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3155*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3156*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
3157*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62 3158 *rT = (unsigned32)CR;
45525d8d 3159 PPC_INSN_MFCR(RT_BITMASK);
c143ef62
MM
3160
3161#
3162# I.4.6.2 Floating-Point Load Instructions
3163#
3164
31650.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single
54e98699
MM
3166*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3167*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3168*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3169*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3170 unsigned_word b;
3171 unsigned_word EA;
3172 if (RA == 0) b = 0;
3173 else b = *rA;
3174 EA = b + EXTS(D);
3175 *frT = DOUBLE(MEM(unsigned, EA, 4));
45525d8d 3176 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3177
c143ef62 31780.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed
54e98699
MM
3179*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3180*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3181*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3182*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3183 unsigned_word b;
3184 unsigned_word EA;
3185 if (RA == 0) b = 0;
3186 else b = *rA;
3187 EA = b + *rB;
3188 *frT = DOUBLE(MEM(unsigned, EA, 4));
45525d8d 3189 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 3190
c143ef62 31910.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update
54e98699
MM
3192*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3193*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3194*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3195*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3196 unsigned_word EA;
3197 if (RA == 0)
3198 program_interrupt(processor, cia,
3199 illegal_instruction_program_interrupt);
3200 EA = *rA + EXTS(D);
3201 *frT = DOUBLE(MEM(unsigned, EA, 4));
3202 *rA = EA;
45525d8d 3203 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3204
c143ef62 32050.31,6.FRT,11.RA,16.RB,21.576,31./:X:f::Load Floating-Point Single with Update Indexed
54e98699
MM
3206*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3207*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3208*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3209*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3210 unsigned_word EA;
3211 if (RA == 0)
3212 program_interrupt(processor, cia,
3213 illegal_instruction_program_interrupt);
3214 EA = *rA + *rB;
3215 *frT = DOUBLE(MEM(unsigned, EA, 4));
3216 *rA = EA;
45525d8d 3217 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
3218
32190.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double
54e98699
MM
3220*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3221*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3222*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3223*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3224 unsigned_word b;
3225 unsigned_word EA;
3226 if (RA == 0) b = 0;
3227 else b = *rA;
3228 EA = b + EXTS(D);
3229 *frT = MEM(unsigned, EA, 8);
45525d8d 3230 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3231
c143ef62 32320.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed
54e98699
MM
3233*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3234*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3235*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3236*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3237 unsigned_word b;
3238 unsigned_word EA;
3239 if (RA == 0) b = 0;
3240 else b = *rA;
3241 EA = b + *rB;
3242 *frT = MEM(unsigned, EA, 8);
45525d8d 3243 PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
845ff5a4 3244
c143ef62 32450.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update
54e98699
MM
3246*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3247*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3248*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3249*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3250 unsigned_word EA;
3251 if (RA == 0)
3252 program_interrupt(processor, cia,
3253 illegal_instruction_program_interrupt);
3254 EA = *rA + EXTS(D);
3255 *frT = MEM(unsigned, EA, 8);
3256 *rA = EA;
45525d8d 3257 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0);
845ff5a4 3258
c143ef62 32590.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed
54e98699
MM
3260*601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0
3261*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3262*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3263*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3264 unsigned_word EA;
3265 if (RA == 0)
3266 program_interrupt(processor, cia,
3267 illegal_instruction_program_interrupt);
3268 EA = *rA + *rB;
3269 *frT = MEM(unsigned, EA, 8);
3270 *rA = EA;
45525d8d 3271 PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
3272
3273
3274#
3275# I.4.6.3 Floating-Point Store Instructions
3276#
3277
32780.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single
54e98699
MM
3279*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3280*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3281*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3282*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3283 unsigned_word b;
3284 unsigned_word EA;
3285 if (RA == 0) b = 0;
3286 else b = *rA;
3287 EA = b + EXTS(D);
3288 STORE(EA, 4, SINGLE(*frS));
45525d8d 3289 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3290
c143ef62 32910.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed
54e98699
MM
3292*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3293*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3294*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3295*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3296 unsigned_word b;
3297 unsigned_word EA;
3298 if (RA == 0) b = 0;
3299 else b = *rA;
3300 EA = b + *rB;
3301 STORE(EA, 4, SINGLE(*frS));
45525d8d 3302 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
845ff5a4 3303
c143ef62 33040.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update
54e98699
MM
3305*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3306*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3307*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3308*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3309 unsigned_word EA;
3310 if (RA == 0)
3311 program_interrupt(processor, cia,
3312 illegal_instruction_program_interrupt);
3313 EA = *rA + EXTS(D);
3314 STORE(EA, 4, SINGLE(*frS));
3315 *rA = EA;
45525d8d 3316 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3317
c143ef62 33180.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed
54e98699
MM
3319*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3320*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3321*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3322*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3323 unsigned_word EA;
3324 if (RA == 0)
3325 program_interrupt(processor, cia,
3326 illegal_instruction_program_interrupt);
3327 EA = *rA + *rB;
3328 STORE(EA, 4, SINGLE(*frS));
3329 *rA = EA;
45525d8d 3330 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
c143ef62
MM
3331
33320.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double
54e98699
MM
3333*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3334*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3335*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3336*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3337 unsigned_word b;
3338 unsigned_word EA;
3339 if (RA == 0) b = 0;
3340 else b = *rA;
3341 EA = b + EXTS(D);
3342 STORE(EA, 8, *frS);
45525d8d 3343 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3344
c143ef62 33450.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed
54e98699
MM
3346*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3347*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3348*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3349*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3350 unsigned_word b;
3351 unsigned_word EA;
3352 if (RA == 0) b = 0;
3353 else b = *rA;
3354 EA = b + *rB;
3355 STORE(EA, 8, *frS);
45525d8d 3356 PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
845ff5a4 3357
c143ef62 33580.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update
54e98699
MM
3359*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3360*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3361*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3362*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3363 unsigned_word EA;
3364 if (RA == 0)
3365 program_interrupt(processor, cia,
3366 illegal_instruction_program_interrupt);
3367 EA = *rA + EXTS(D);
3368 STORE(EA, 8, *frS);
3369 *rA = EA;
45525d8d 3370 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK);
845ff5a4 3371
c143ef62 33720.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed
54e98699
MM
3373*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
3374*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3375*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0
3376*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
c143ef62
MM
3377 unsigned_word EA;
3378 if (RA == 0)
3379 program_interrupt(processor, cia,
3380 illegal_instruction_program_interrupt);
3381 EA = *rA + *rB;
3382 STORE(EA, 8, *frS);
3383 *rA = EA;
45525d8d 3384 PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK);
c143ef62
MM
3385
3386
3387#
3388# I.4.6.4 Floating-Point Move Instructions
3389#
3390
33910.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register
54e98699
MM
3392*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3393*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3394*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3395*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3396 *frT = *frB;
3397 CR1_UPDATE(Rc);
45525d8d 3398 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 3399
c143ef62 34000.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate
54e98699
MM
3401*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3402*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3403*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3404*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3405 *frT = *frB ^ BIT64(0);
3406 CR1_UPDATE(Rc);
45525d8d 3407 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 3408
c143ef62 34090.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value
54e98699
MM
3410*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3411*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3412*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3413*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3414 *frT = *frB & ~BIT64(0);
3415 CR1_UPDATE(Rc);
45525d8d 3416 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 3417
c143ef62 34180.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value
54e98699
MM
3419*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3420*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3421*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3422*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3423 *frT = *frB | BIT64(0);
3424 CR1_UPDATE(Rc);
45525d8d 3425 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
c143ef62
MM
3426
3427
3428#
3429# I.4.6.5 Floating-Point Arithmetic Instructions
3430#
3431
34320.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add
54e98699
MM
3433*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3434*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3435*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3436*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3437 FPSCR_BEGIN;
3438 if (is_invalid_operation(processor, cia,
3439 *frA, *frB,
3440 fpscr_vxsnan | fpscr_vxisi,
3441 0, /*single?*/
3442 0) /*negate?*/) {
3443 invalid_arithemetic_operation(processor, cia,
3444 frT, *frA, *frB, 0,
3445 0, /*instruction_is_frsp*/
3446 0, /*instruction_is_convert_to_64bit*/
3447 0, /*instruction_is_convert_to_32bit*/
3448 0); /*single-precision*/
3449 }
3450 else {
3451 /*HACK!*/
3452 double s = *(double*)frA + *(double*)frB;
3453 *(double*)frT = s;
3454 }
3455 FPSCR_END(Rc);
45525d8d 3456 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
845ff5a4 3457
c143ef62 34580.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single
54e98699
MM
3459*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3460*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3461*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3462*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3463 FPSCR_BEGIN;
3464 if (is_invalid_operation(processor, cia,
3465 *frA, *frB,
3466 fpscr_vxsnan | fpscr_vxisi,
3467 1, /*single?*/
3468 0) /*negate?*/) {
3469 invalid_arithemetic_operation(processor, cia,
3470 frT, *frA, *frB, 0,
3471 0, /*instruction_is_frsp*/
3472 0, /*instruction_is_convert_to_64bit*/
3473 0, /*instruction_is_convert_to_32bit*/
3474 1); /*single-precision*/
3475 }
3476 else {
3477 /*HACK!*/
3478 float s = *(double*)frA + *(double*)frB;
3479 *(double*)frT = s;
3480 }
3481 FPSCR_END(Rc);
45525d8d 3482 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
c143ef62
MM
3483
34840.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract
54e98699
MM
3485*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3486*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3487*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3488*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3489 FPSCR_BEGIN;
3490 if (is_invalid_operation(processor, cia,
3491 *frA, *frB,
3492 fpscr_vxsnan | fpscr_vxisi,
3493 0, /*single?*/
3494 1) /*negate?*/) {
3495 invalid_arithemetic_operation(processor, cia,
3496 frT, *frA, *frB, 0,
3497 0, /*instruction_is_frsp*/
3498 0, /*instruction_is_convert_to_64bit*/
3499 0, /*instruction_is_convert_to_32bit*/
3500 0); /*single-precision*/
3501 }
3502 else {
3503 /*HACK!*/
3504 double s = *(double*)frA - *(double*)frB;
3505 *(double*)frT = s;
3506 }
3507 FPSCR_END(Rc);
45525d8d 3508 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
845ff5a4 3509
c143ef62 35100.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single
54e98699
MM
3511*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3512*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3513*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3514*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3515 FPSCR_BEGIN;
3516 if (is_invalid_operation(processor, cia,
3517 *frA, *frB,
3518 fpscr_vxsnan | fpscr_vxisi,
3519 1, /*single?*/
3520 1) /*negate?*/) {
3521 invalid_arithemetic_operation(processor, cia,
3522 frT, *frA, *frB, 0,
3523 0, /*instruction_is_frsp*/
3524 0, /*instruction_is_convert_to_64bit*/
3525 0, /*instruction_is_convert_to_32bit*/
3526 1); /*single-precision*/
3527 }
3528 else {
3529 /*HACK!*/
3530 float s = *(double*)frA - *(double*)frB;
3531 *(double*)frT = s;
3532 }
3533 FPSCR_END(Rc);
45525d8d 3534 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
c143ef62
MM
3535
35360.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply
54e98699
MM
3537*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3538*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3539*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3540*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3541 FPSCR_BEGIN;
3542 if (is_invalid_operation(processor, cia,
3543 *frA, *frC,
3544 fpscr_vxsnan | fpscr_vximz,
3545 0, /*single?*/
3546 0) /*negate?*/) {
3547 invalid_arithemetic_operation(processor, cia,
3548 frT, *frA, 0, *frC,
3549 0, /*instruction_is_frsp*/
3550 0, /*instruction_is_convert_to_64bit*/
3551 0, /*instruction_is_convert_to_32bit*/
3552 0); /*single-precision*/
3553 }
3554 else {
3555 /*HACK!*/
3556 double s = *(double*)frA * *(double*)frC;
3557 *(double*)frT = s;
3558 }
3559 FPSCR_END(Rc);
45525d8d 3560 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3561
c143ef62 35620.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single
54e98699
MM
3563*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3564*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3565*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3566*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3567 FPSCR_BEGIN;
3568 if (is_invalid_operation(processor, cia,
3569 *frA, *frC,
3570 fpscr_vxsnan | fpscr_vximz,
3571 1, /*single?*/
3572 0) /*negate?*/) {
3573 invalid_arithemetic_operation(processor, cia,
3574 frT, *frA, 0, *frC,
3575 0, /*instruction_is_frsp*/
3576 0, /*instruction_is_convert_to_64bit*/
3577 0, /*instruction_is_convert_to_32bit*/
3578 1); /*single-precision*/
3579 }
3580 else {
3581 /*HACK!*/
3582 float s = *(double*)frA * *(double*)frC;
3583 *(double*)frT = s;
3584 }
3585 FPSCR_END(Rc);
45525d8d 3586 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3587
35880.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide
54e98699
MM
3589*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0
3590*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3591*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0
3592*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0
c143ef62
MM
3593 FPSCR_BEGIN;
3594 if (is_invalid_operation(processor, cia,
3595 *frA, *frB,
3596 fpscr_vxsnan | fpscr_vxzdz,
3597 0, /*single?*/
3598 0) /*negate?*/) {
3599 invalid_arithemetic_operation(processor, cia,
3600 frT, *frA, *frB, 0,
3601 0, /*instruction_is_frsp*/
3602 0, /*instruction_is_convert_to_64bit*/
3603 0, /*instruction_is_convert_to_32bit*/
3604 0); /*single-precision*/
3605 }
3606 else {
3607 /*HACK!*/
3608 double s = *(double*)frA / *(double*)frB;
3609 *(double*)frT = s;
3610 }
3611 FPSCR_END(Rc);
45525d8d 3612 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
845ff5a4 3613
c143ef62 36140.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single
54e98699
MM
3615*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0
3616*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3617*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
3618*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0
c143ef62
MM
3619 FPSCR_BEGIN;
3620 if (is_invalid_operation(processor, cia,
3621 *frA, *frB,
3622 fpscr_vxsnan | fpscr_vxzdz,
3623 1, /*single?*/
3624 0) /*negate?*/) {
3625 invalid_arithemetic_operation(processor, cia,
3626 frT, *frA, *frB, 0,
3627 0, /*instruction_is_frsp*/
3628 0, /*instruction_is_convert_to_64bit*/
3629 0, /*instruction_is_convert_to_32bit*/
3630 1); /*single-precision*/
3631 }
3632 else {
3633 /*HACK!*/
3634 float s = *(double*)frA / *(double*)frB;
3635 *(double*)frT = s;
3636 }
3637 FPSCR_END(Rc);
45525d8d 3638 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc);
c143ef62
MM
3639
36400.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add
54e98699
MM
3641*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3642*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3643*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3644*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
3645 FPSCR_BEGIN;
3646 double product; /*HACK! - incorrectly loosing precision ... */
3647 /* compute the multiply */
3648 if (is_invalid_operation(processor, cia,
3649 *frA, *frC,
3650 fpscr_vxsnan | fpscr_vximz,
3651 0, /*single?*/
3652 0) /*negate?*/) {
3653 invalid_arithemetic_operation(processor, cia,
3654 (unsigned64*)&product, *frA, 0, *frC,
3655 0, /*instruction_is_frsp*/
3656 0, /*instruction_is_convert_to_64bit*/
3657 0, /*instruction_is_convert_to_32bit*/
3658 0); /*single-precision*/
3659 }
3660 else {
3661 /*HACK!*/
3662 product = *(double*)frA * *(double*)frC;
3663 }
3664 /* compute the add */
3665 if (is_invalid_operation(processor, cia,
3666 product, *frB,
3667 fpscr_vxsnan | fpscr_vxisi,
3668 0, /*single?*/
3669 0) /*negate?*/) {
3670 invalid_arithemetic_operation(processor, cia,
3671 frT, product, *frB, 0,
3672 0, /*instruction_is_frsp*/
3673 0, /*instruction_is_convert_to_64bit*/
3674 0, /*instruction_is_convert_to_32bit*/
3675 0); /*single-precision*/
3676 }
3677 else {
3678 /*HACK!*/
3679 double s = product + *(double*)frB;
3680 *(double*)frT = s;
3681 }
3682 FPSCR_END(Rc);
45525d8d 3683 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3684
c143ef62 36850.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single
54e98699
MM
3686*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3687*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3688*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3689*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3690 FPSCR_BEGIN;
3691 float product; /*HACK! - incorrectly loosing precision ... */
3692 /* compute the multiply */
3693 if (is_invalid_operation(processor, cia,
3694 *frA, *frC,
3695 fpscr_vxsnan | fpscr_vximz,
3696 1, /*single?*/
3697 0) /*negate?*/) {
3698 invalid_arithemetic_operation(processor, cia,
3699 (unsigned64*)&product, *frA, 0, *frC,
3700 0, /*instruction_is_frsp*/
3701 0, /*instruction_is_convert_to_64bit*/
3702 0, /*instruction_is_convert_to_32bit*/
3703 0); /*single-precision*/
3704 }
3705 else {
3706 /*HACK!*/
3707 product = *(double*)frA * *(double*)frC;
3708 }
3709 /* compute the add */
3710 if (is_invalid_operation(processor, cia,
3711 product, *frB,
3712 fpscr_vxsnan | fpscr_vxisi,
3713 1, /*single?*/
3714 0) /*negate?*/) {
3715 invalid_arithemetic_operation(processor, cia,
3716 frT, product, *frB, 0,
3717 0, /*instruction_is_frsp*/
3718 0, /*instruction_is_convert_to_64bit*/
3719 0, /*instruction_is_convert_to_32bit*/
3720 0); /*single-precision*/
3721 }
3722 else {
3723 /*HACK!*/
3724 float s = product + *(double*)frB;
3725 *(double*)frT = (double)s;
3726 }
3727 FPSCR_END(Rc);
45525d8d 3728 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
4a0351ab
MM
3729
37300.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract
3731*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3732*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3733*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
54e98699 3734*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3735 FPSCR_BEGIN;
3736 double product; /*HACK! - incorrectly loosing precision ... */
3737 /* compute the multiply */
3738 if (is_invalid_operation(processor, cia,
3739 *frA, *frC,
3740 fpscr_vxsnan | fpscr_vximz,
3741 0, /*single?*/
3742 0) /*negate?*/) {
3743 invalid_arithemetic_operation(processor, cia,
3744 (unsigned64*)&product, *frA, 0, *frC,
3745 0, /*instruction_is_frsp*/
3746 0, /*instruction_is_convert_to_64bit*/
3747 0, /*instruction_is_convert_to_32bit*/
3748 0); /*single-precision*/
3749 }
3750 else {
3751 /*HACK!*/
3752 product = *(double*)frA * *(double*)frC;
3753 }
3754 /* compute the subtract */
3755 if (is_invalid_operation(processor, cia,
3756 product, *frB,
3757 fpscr_vxsnan | fpscr_vxisi,
3758 0, /*single?*/
3759 0) /*negate?*/) {
3760 invalid_arithemetic_operation(processor, cia,
3761 frT, product, *frB, 0,
3762 0, /*instruction_is_frsp*/
3763 0, /*instruction_is_convert_to_64bit*/
3764 0, /*instruction_is_convert_to_32bit*/
3765 0); /*single-precision*/
3766 }
3767 else {
3768 /*HACK!*/
3769 double s = product - *(double*)frB;
3770 *(double*)frT = s;
3771 }
3772 FPSCR_END(Rc);
45525d8d 3773 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3774
c143ef62 37750.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single
54e98699
MM
3776*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3777*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3778*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3779*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3780 FPSCR_BEGIN;
3781 float product; /*HACK! - incorrectly loosing precision ... */
3782 /* compute the multiply */
3783 if (is_invalid_operation(processor, cia,
3784 *frA, *frC,
3785 fpscr_vxsnan | fpscr_vximz,
3786 1, /*single?*/
3787 0) /*negate?*/) {
3788 invalid_arithemetic_operation(processor, cia,
3789 (unsigned64*)&product, *frA, 0, *frC,
3790 0, /*instruction_is_frsp*/
3791 0, /*instruction_is_convert_to_64bit*/
3792 0, /*instruction_is_convert_to_32bit*/
3793 0); /*single-precision*/
3794 }
3795 else {
3796 /*HACK!*/
3797 product = *(double*)frA * *(double*)frC;
3798 }
3799 /* compute the subtract */
3800 if (is_invalid_operation(processor, cia,
3801 product, *frB,
3802 fpscr_vxsnan | fpscr_vxisi,
3803 1, /*single?*/
3804 0) /*negate?*/) {
3805 invalid_arithemetic_operation(processor, cia,
3806 frT, product, *frB, 0,
3807 0, /*instruction_is_frsp*/
3808 0, /*instruction_is_convert_to_64bit*/
3809 0, /*instruction_is_convert_to_32bit*/
3810 0); /*single-precision*/
3811 }
3812 else {
3813 /*HACK!*/
3814 float s = product - *(double*)frB;
3815 *(double*)frT = (double)s;
3816 }
3817 FPSCR_END(Rc);
45525d8d 3818 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3819
38200.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add
54e98699
MM
3821*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3822*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3823*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3824*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3825 FPSCR_BEGIN;
3826 double product; /*HACK! - incorrectly loosing precision ... */
3827 /* compute the multiply */
3828 if (is_invalid_operation(processor, cia,
3829 *frA, *frC,
3830 fpscr_vxsnan | fpscr_vximz,
3831 0, /*single?*/
3832 0) /*negate?*/) {
3833 invalid_arithemetic_operation(processor, cia,
3834 (unsigned64*)&product, *frA, 0, *frC,
3835 0, /*instruction_is_frsp*/
3836 0, /*instruction_is_convert_to_64bit*/
3837 0, /*instruction_is_convert_to_32bit*/
3838 0); /*single-precision*/
3839 }
3840 else {
3841 /*HACK!*/
3842 product = *(double*)frA * *(double*)frC;
3843 }
3844 /* compute the add */
3845 if (is_invalid_operation(processor, cia,
3846 product, *frB,
3847 fpscr_vxsnan | fpscr_vxisi,
3848 0, /*single?*/
3849 0) /*negate?*/) {
3850 invalid_arithemetic_operation(processor, cia,
3851 frT, product, *frB, 0,
3852 0, /*instruction_is_frsp*/
3853 0, /*instruction_is_convert_to_64bit*/
3854 0, /*instruction_is_convert_to_32bit*/
3855 0); /*single-precision*/
3856 }
3857 else {
3858 /*HACK!*/
3859 double s = -(product + *(double*)frB);
3860 *(double*)frT = s;
3861 }
3862 FPSCR_END(Rc);
45525d8d 3863 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3864
c143ef62 38650.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single
54e98699
MM
3866*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3867*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3868*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3869*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3870 FPSCR_BEGIN;
3871 float product; /*HACK! - incorrectly loosing precision ... */
3872 /* compute the multiply */
3873 if (is_invalid_operation(processor, cia,
3874 *frA, *frC,
3875 fpscr_vxsnan | fpscr_vximz,
3876 1, /*single?*/
3877 0) /*negate?*/) {
3878 invalid_arithemetic_operation(processor, cia,
3879 (unsigned64*)&product, *frA, 0, *frC,
3880 0, /*instruction_is_frsp*/
3881 0, /*instruction_is_convert_to_64bit*/
3882 0, /*instruction_is_convert_to_32bit*/
3883 0); /*single-precision*/
3884 }
3885 else {
3886 /*HACK!*/
3887 product = *(double*)frA * *(double*)frC;
3888 }
3889 /* compute the add */
3890 if (is_invalid_operation(processor, cia,
3891 product, *frB,
3892 fpscr_vxsnan | fpscr_vxisi,
3893 1, /*single?*/
3894 0) /*negate?*/) {
3895 invalid_arithemetic_operation(processor, cia,
3896 frT, product, *frB, 0,
3897 0, /*instruction_is_frsp*/
3898 0, /*instruction_is_convert_to_64bit*/
3899 0, /*instruction_is_convert_to_32bit*/
3900 0); /*single-precision*/
3901 }
3902 else {
3903 /*HACK!*/
3904 float s = -(product + *(double*)frB);
3905 *(double*)frT = (double)s;
3906 }
3907 FPSCR_END(Rc);
45525d8d 3908 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3909
39100.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract
54e98699
MM
3911*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0
3912*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3913*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0
3914*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3915 FPSCR_BEGIN;
3916 double product; /*HACK! - incorrectly loosing precision ... */
3917 /* compute the multiply */
3918 if (is_invalid_operation(processor, cia,
3919 *frA, *frC,
3920 fpscr_vxsnan | fpscr_vximz,
3921 0, /*single?*/
3922 0) /*negate?*/) {
3923 invalid_arithemetic_operation(processor, cia,
3924 (unsigned64*)&product, *frA, 0, *frC,
3925 0, /*instruction_is_frsp*/
3926 0, /*instruction_is_convert_to_64bit*/
3927 0, /*instruction_is_convert_to_32bit*/
3928 0); /*single-precision*/
3929 }
3930 else {
3931 /*HACK!*/
3932 product = *(double*)frA * *(double*)frC;
3933 }
3934 /* compute the subtract */
3935 if (is_invalid_operation(processor, cia,
3936 product, *frB,
3937 fpscr_vxsnan | fpscr_vxisi,
3938 0, /*single?*/
3939 0) /*negate?*/) {
3940 invalid_arithemetic_operation(processor, cia,
3941 frT, product, *frB, 0,
3942 0, /*instruction_is_frsp*/
3943 0, /*instruction_is_convert_to_64bit*/
3944 0, /*instruction_is_convert_to_32bit*/
3945 0); /*single-precision*/
3946 }
3947 else {
3948 /*HACK!*/
3949 double s = -(product - *(double*)frB);
3950 *(double*)frT = s;
3951 }
3952 FPSCR_END(Rc);
45525d8d 3953 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
845ff5a4 3954
c143ef62 39550.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single
54e98699
MM
3956*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
3957*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3958*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
3959*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4a0351ab
MM
3960 FPSCR_BEGIN;
3961 float product; /*HACK! - incorrectly loosing precision ... */
3962 /* compute the multiply */
3963 if (is_invalid_operation(processor, cia,
3964 *frA, *frC,
3965 fpscr_vxsnan | fpscr_vximz,
3966 1, /*single?*/
3967 0) /*negate?*/) {
3968 invalid_arithemetic_operation(processor, cia,
3969 (unsigned64*)&product, *frA, 0, *frC,
3970 0, /*instruction_is_frsp*/
3971 0, /*instruction_is_convert_to_64bit*/
3972 0, /*instruction_is_convert_to_32bit*/
3973 0); /*single-precision*/
3974 }
3975 else {
3976 /*HACK!*/
3977 product = *(double*)frA * *(double*)frC;
3978 }
3979 /* compute the subtract */
3980 if (is_invalid_operation(processor, cia,
3981 product, *frB,
3982 fpscr_vxsnan | fpscr_vxisi,
3983 1, /*single?*/
3984 0) /*negate?*/) {
3985 invalid_arithemetic_operation(processor, cia,
3986 frT, product, *frB, 0,
3987 0, /*instruction_is_frsp*/
3988 0, /*instruction_is_convert_to_64bit*/
3989 0, /*instruction_is_convert_to_32bit*/
3990 0); /*single-precision*/
3991 }
3992 else {
3993 /*HACK!*/
3994 float s = -(product - *(double*)frB);
3995 *(double*)frT = (double)s;
3996 }
3997 FPSCR_END(Rc);
45525d8d 3998 PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc);
c143ef62
MM
3999
4000
4001#
4002# I.4.6.6 Floating-Point Rounding and Conversion Instructions
4003#
4004
40050.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision
54e98699
MM
4006*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4007*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4008*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4009*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4010 int sign;
4011 int exp;
4012 unsigned64 frac_grx;
30c87b55
MM
4013 enum { start, finish, Disabled_Exponent_Underflow, Enabled_Exponent_Underflow, Disabled_Exponent_Overflow, Enabled_Exponent_Overflow, Normal_Operand, Zero_Operand, Infinity_Operand, QNaN_Operand, SNaN_Operand, Enabled_Overflow, Done } label = start;
4014 while (label != finish) switch (label) {
4015 case finish:
4016 error("Unhandled switch\n");
4017 case start:
4018 /* split off cases for what to do */
4019 if (EXTRACTED64(*frB, 1, 11) < 897
4020 && EXTRACTED64(*frB, 1, 63) > 0) {
4021 if ((FPSCR & fpscr_ue) == 0) { label = Disabled_Exponent_Underflow; break; }
4022 if ((FPSCR & fpscr_ue) != 0) { label = Enabled_Exponent_Underflow; break; }
4023 }
4024 if (EXTRACTED64(*frB, 1, 11) > 1150
4025 && EXTRACTED64(*frB, 1, 11) < 2047) {
4026 if ((FPSCR & fpscr_oe) == 0) { label = Disabled_Exponent_Overflow; break; }
4027 if ((FPSCR & fpscr_oe) != 0) { label = Enabled_Exponent_Overflow; break; }
4028 }
4029 if (EXTRACTED64(*frB, 1, 11) > 896
4030 && EXTRACTED64(*frB, 1, 11) < 1151) { label = Normal_Operand; break; }
4031 if (EXTRACTED64(*frB, 1, 63) == 0) { label = Zero_Operand; break; }
4032 if (EXTRACTED64(*frB, 1, 11) == 2047) {
4033 if (EXTRACTED64(*frB, 12, 63) == 0) { label = Infinity_Operand; break; }
4034 if (EXTRACTED64(*frB, 12, 12) == 1) { label = QNaN_Operand; break; }
4035 if (EXTRACTED64(*frB, 12, 12) == 0
4036 && EXTRACTED64(*frB, 13, 63) > 0) { label = SNaN_Operand; break; }
4037 }
4038 case Disabled_Exponent_Underflow:
c143ef62
MM
4039 sign = EXTRACTED64(*frB, 0, 0);
4040 if (EXTRACTED64(*frB, 1, 11) == 0) {
4041 exp = -1022;
4042 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4043 }
4044 if (EXTRACTED64(*frB, 1, 11) > 0) {
4045 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4046 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4047 }
c143ef62
MM
4048 /* G|R|X == zero from above */
4049 while (exp < -126) {
4050 exp = exp - 1;
4051 frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55)
4052 | MASKED64(frac_grx, 55, 55));
4053 }
4054 FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0);
4055 Round_Single(processor, sign, &exp, &frac_grx);
4056 FPSCR_SET_XX(FPSCR & fpscr_fi);
4057 if (EXTRACTED64(frac_grx, 0, 52) == 0) {
4058 *frT = INSERTED64(sign, 0, 0);
4059 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4060 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4061 }
4062 if (EXTRACTED64(frac_grx, 0, 52) > 0) {
4063 if (EXTRACTED64(frac_grx, 0, 0) == 1) {
4064 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4065 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4066 }
4067 if (EXTRACTED64(frac_grx, 0, 0) == 0) {
4068 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number);
4069 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number);
4070 }
4071 /*Normalize_Operand:*/
4072 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4073 exp = exp - 1;
4074 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4075 }
4076 *frT = (INSERTED64(sign, 0, 0)
4077 | INSERTED64(exp + 1023, 1, 11)
4078 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4079 }
30c87b55
MM
4080 { label = Done; break; }
4081 case Enabled_Exponent_Underflow:
c143ef62
MM
4082 FPSCR_SET_UX(1);
4083 sign = EXTRACTED64(*frB, 0, 0);
4084 if (EXTRACTED64(*frB, 1, 11) == 0) {
4085 exp = -1022;
4086 frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4087 }
4088 if (EXTRACTED64(*frB, 1, 11) > 0) {
4089 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4090 frac_grx = (BIT64(0) |
4091 INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52));
4092 }
4093 /*Normalize_Operand:*/
4094 while (EXTRACTED64(frac_grx, 0, 0) == 0) {
4095 exp = exp - 1;
4096 frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51);
4097 }
4098 Round_Single(processor, sign, &exp, &frac_grx);
4099 FPSCR_SET_XX(FPSCR & fpscr_fi);
4100 exp = exp + 192;
4101 *frT = (INSERTED64(sign, 0, 0)
4102 | INSERTED64(exp + 1023, 1, 11)
4103 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4104 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4105 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
30c87b55
MM
4106 { label = Done; break; }
4107 case Disabled_Exponent_Overflow:
c143ef62
MM
4108 FPSCR_SET_OX(1);
4109 if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) {
4110 if (EXTRACTED64(*frB, 0, 0) == 0) {
4111 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4112 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4113 }
4114 if (EXTRACTED64(*frB, 0, 0) == 1) {
4115 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4116 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4117 }
4118 }
4119 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) {
4120 if (EXTRACTED64(*frB, 0, 0) == 0) {
4121 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4122 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4123 }
4124 if (EXTRACTED64(*frB, 0, 0) == 1) {
4125 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4126 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4127 }
4128 }
4129 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) {
4130 if (EXTRACTED64(*frB, 0, 0) == 0) {
4131 *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000;
4132 FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4133 }
4134 if (EXTRACTED64(*frB, 0, 0) == 1) {
4135 *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000;
4136 FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4137 }
4138 }
4139 if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) {
4140 if (EXTRACTED64(*frB, 0, 0) == 0) {
4141 *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000;
4142 FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4143 }
4144 if (EXTRACTED64(*frB, 0, 0) == 1) {
4145 *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000;
4146 FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4147 }
4148 }
4149 /* FPSCR[FR] <- undefined */
4150 FPSCR_SET_FI(1);
4151 FPSCR_SET_XX(1);
30c87b55
MM
4152 { label = Done; break; }
4153 case Enabled_Exponent_Overflow:
c143ef62
MM
4154 sign = EXTRACTED64(*frB, 0, 0);
4155 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4156 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4157 Round_Single(processor, sign, &exp, &frac_grx);
4158 FPSCR_SET_XX(FPSCR & fpscr_fi);
30c87b55
MM
4159 case Enabled_Overflow:
4160 FPSCR_SET_OX(1);
4161 exp = exp - 192;
4162 *frT = (INSERTED64(sign, 0, 0)
4163 | INSERTED64(exp + 1023, 1, 11)
4164 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4165 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4166 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
4167 { label = Done; break; }
4168 case Zero_Operand:
c143ef62
MM
4169 *frT = *frB;
4170 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4171 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero);
4172 FPSCR_SET_FR(0);
4173 FPSCR_SET_FI(0);
30c87b55
MM
4174 { label = Done; break; }
4175 case Infinity_Operand:
c143ef62
MM
4176 *frT = *frB;
4177 if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
4178 if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
4179 FPSCR_SET_FR(0);
4180 FPSCR_SET_FI(0);
30c87b55
MM
4181 { label = Done; break; }
4182 case QNaN_Operand:
c143ef62
MM
4183 *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34);
4184 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4185 FPSCR_SET_FR(0);
4186 FPSCR_SET_FI(0);
30c87b55
MM
4187 { label = Done; break; }
4188 case SNaN_Operand:
c143ef62
MM
4189 FPSCR_OR_VX(fpscr_vxsnan);
4190 if ((FPSCR & fpscr_ve) == 0) {
4191 *frT = (MASKED64(*frB, 0, 11)
4192 | BIT64(12)
4193 | MASKED64(*frB, 13, 34));
4194 FPSCR_SET_FPRF(fpscr_rf_quiet_nan);
4195 }
4196 FPSCR_SET_FR(0);
4197 FPSCR_SET_FI(0);
30c87b55
MM
4198 { label = Done; break; }
4199 case Normal_Operand:
c143ef62
MM
4200 sign = EXTRACTED64(*frB, 0, 0);
4201 exp = EXTRACTED64(*frB, 1, 11) - 1023;
4202 frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52);
4203 Round_Single(processor, sign, &exp, &frac_grx);
4204 FPSCR_SET_XX(FPSCR & fpscr_fi);
30c87b55
MM
4205 if (exp > 127 && (FPSCR & fpscr_oe) == 0) { label = Disabled_Exponent_Overflow; break; }
4206 if (exp > 127 && (FPSCR & fpscr_oe) != 0) { label = Enabled_Overflow; break; }
c143ef62
MM
4207 *frT = (INSERTED64(sign, 0, 0)
4208 | INSERTED64(exp + 1023, 1, 11)
4209 | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63));
4210 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4211 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number);
30c87b55
MM
4212 { label = Done; break; }
4213 case Done:
4214 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4215 { label = finish; break; }
4216 }
845ff5a4 4217
c143ef62 42180.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword
845ff5a4 4219
c143ef62 42200.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero
845ff5a4 4221
c143ef62 42220.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word
845ff5a4 4223
c143ef62 42240.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero
54e98699
MM
4225*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4226*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4227*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4228*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4229 FPSCR_BEGIN;
4230 convert_to_integer(processor, cia,
4231 frT, *frB,
4232 fpscr_rn_round_towards_zero, 32);
4233 FPSCR_END(Rc);
45525d8d 4234 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
845ff5a4 4235
c143ef62
MM
42360.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword
4237 int sign = EXTRACTED64(*frB, 0, 0);
4238 int exp = 63;
4239 unsigned64 frac = *frB;
30c87b55
MM
4240 enum { start, finish, Zero_Operand, Done } label = start;
4241 while (label != finish) switch (label) {
4242 case finish:
4243 error("Unhandled switch\n");
4244 case start:
4245 if (frac == 0) { label = Zero_Operand; break; }
4246 if (sign == 1) frac = ~frac + 1;
4247 while (EXTRACTED64(frac, 0, 0) == 0) {
4248 /*??? do the loop 0 times if (FRB) = max negative integer */
4249 frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62);
4250 exp = exp - 1;
4251 }
4252 Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn);
4253 if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4254 if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number);
4255 *frT = (INSERTED64(sign, 0, 0)
4256 | INSERTED64(exp + 1023, 1, 11)
4257 | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63));
4258 { label = Done; break; }
c143ef62 4259 /**/
30c87b55 4260 case Zero_Operand:
c143ef62
MM
4261 FPSCR_SET_FR(0);
4262 FPSCR_SET_FI(0);
4263 FPSCR_SET_FPRF(fpscr_rf_pos_zero);
4264 *frT = 0;
30c87b55 4265 { label = Done; break; }
c143ef62 4266 /**/
30c87b55
MM
4267 case Done:
4268 PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc);
4269 { label = finish; break; }
4270 }
c143ef62
MM
4271
4272#
4273# I.4.6.7 Floating-Point Compare Instructions
4274#
4275
42760.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered
54e98699
MM
4277*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4278*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4279*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4280*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4281 FPSCR_BEGIN;
4282 unsigned c;
4283 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4284 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4285 else if (is_less_than(frA, frB))
4286 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4287 else if (is_greater_than(frA, frB))
4288 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4289 else
4290 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4291 FPSCR_SET_FPCC(c);
4292 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4293 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0))
4294 FPSCR_OR_VX(fpscr_vxsnan);
4295 FPSCR_END(0);
45525d8d 4296 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
845ff5a4 4297
c143ef62 42980.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered
54e98699
MM
4299*601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0
4300*603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4301*603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
4302*604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0
c143ef62
MM
4303 FPSCR_BEGIN;
4304 unsigned c;
4305 if (is_NaN(*frA, 0) || is_NaN(*frB, 0))
4306 c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */
4307 else if (is_less_than(frA, frB))
4308 c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */
4309 else if (is_greater_than(frA, frB))
4310 c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */
4311 else
4312 c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */
4313 FPSCR_SET_FPCC(c);
4314 CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */
4315 if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) {
4316 FPSCR_OR_VX(fpscr_vxsnan);
4317 if ((FPSCR & fpscr_ve) == 0)
4318 FPSCR_OR_VX(fpscr_vxvc);
4319 }
4320 else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) {
4321 FPSCR_OR_VX(fpscr_vxvc);
4322 }
4323 FPSCR_END(0);
45525d8d 4324 PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK);
c143ef62
MM
4325
4326
4327#
4328# I.4.6.8 Floating-Point Status and Control Register Instructions
4329#
4330
43310.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR
845ff5a4 4332
c143ef62 43330.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR
845ff5a4 4334
c143ef62 43350.64,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate
845ff5a4 4336
c143ef62 43370.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields
845ff5a4 4338
c143ef62 43390.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0
845ff5a4 4340
c143ef62
MM
43410.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1
4342
4343
4344#
4345# I.A.1.1 Floating-Point Store Instruction
4346#
43470.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point as Integer Word Indexed
4348
4349#
4350# I.A.1.2 Floating-Point Arithmetic Instructions
4351#
4352
43530.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root
845ff5a4 4354
c143ef62
MM
43550.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f::Floating Square Root Single
4356
43570.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f::Floating Reciprocal Estimate Single
845ff5a4 4358
c143ef62
MM
43590.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f::Floating Reciprocal Square Root Estimate
4360
4361#
4362# I.A.1.3 Floating-Point Select Instruction
4363#
4364
43650.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f::Floating Select
4366
4367
4368#
4369# II.3.2 Cache Management Instructions
4370#
4371
43720.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate
54e98699
MM
4373*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4374*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4375*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4376*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
80948f39
MM
4377 /* blindly flush all instruction cache entries */
4378 #if WITH_IDECODE_CACHE_SIZE
4379 cpu_flush_icache(processor);
4380 #endif
45525d8d 4381 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0);
c143ef62
MM
4382
43830.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize
54e98699
MM
4384*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4385*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4386*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
4387*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
c143ef62 4388 cpu_synchronize_context(processor);
45525d8d 4389 PPC_INSN_INT(0, 0, 0);
c143ef62
MM
4390
4391
4392#
4393# II.3.2.2 Data Cache Instructions
4394#
4395
43960.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch
54e98699
MM
4397*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4398*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4399*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4400*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
845ff5a4 4401 TRACE(trace_tbd,("Data Cache Block Touch\n"));
45525d8d 4402 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
056e975c 4403
c143ef62 44040.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store
54e98699
MM
4405*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4406*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4407*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4408*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
845ff5a4 4409 TRACE(trace_tbd,("Data Cache Block Touch for Store\n"));
45525d8d 4410 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
056e975c 4411
c143ef62 44120.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero
54e98699
MM
4413*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4414*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4415*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0
4416*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
845ff5a4 4417 TRACE(trace_tbd,("Data Cache Block set to Zero\n"));
45525d8d 4418 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
056e975c 4419
c143ef62 44200.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store
54e98699
MM
4421*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4422*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4423*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4424*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
845ff5a4 4425 TRACE(trace_tbd,("Data Cache Block Store\n"));
45525d8d 4426 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
056e975c 4427
c143ef62 44280.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush
54e98699
MM
4429*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4430*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4431*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0
4432*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0
845ff5a4 4433 TRACE(trace_tbd,("Data Cache Block Flush\n"));
45525d8d 4434 PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/);
c143ef62
MM
4435
4436#
845ff5a4 4437# II.3.3 Enforce In-order Execution of I/O Instruction
c143ef62
MM
4438#
4439
44400.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O
4441 /* Since this model has no instruction overlap
4442 this instruction need do nothing */
4443
4444#
4445# II.4.1 Time Base Instructions
4446#
4447
44480.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base
54e98699
MM
4449*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4450*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4451*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62
MM
4452 int n = (tbr{5:9} << 5) | tbr{0:4};
4453 if (n == 268) {
4454 if (is_64bit_implementation) *rT = TB;
4455 else *rT = EXTRACTED64(TB, 32, 63);
4456 }
4457 else if (n == 269) {
4458 if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31);
4459 else *rT = EXTRACTED64(TB, 0, 31);
4460 }
4461 else
4462 program_interrupt(processor, cia,
4463 illegal_instruction_program_interrupt);
4464
4465
4466#
4467# III.2.3.1 System Linkage Instructions
4468#
4469
80948f39 44700.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt
54e98699
MM
4471*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4472*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4473*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4474*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
80948f39
MM
4475 if (IS_PROBLEM_STATE(processor)) {
4476 program_interrupt(processor, cia,
4477 privileged_instruction_program_interrupt);
4478 }
4479 else {
4480 MSR = (MASKED(SRR1, 0, 32)
4481 | MASKED(SRR1, 37, 41)
4482 | MASKED(SRR1, 48, 63));
4483 NIA = MASKED(SRR0, 0, 61);
4484 cpu_synchronize_context(processor);
30c87b55 4485 check_masked_interrupts(processor);
80948f39 4486 }
c143ef62
MM
4487
4488#
4489# III.3.4.1 Move to/from System Register Instructions
4490#
4491
f2181eff
MM
4492#0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
4493#0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
c143ef62 44940.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
54e98699
MM
4495*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4496*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4497*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4498*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4499 if (IS_PROBLEM_STATE(processor))
4500 program_interrupt(processor, cia,
4501 privileged_instruction_program_interrupt);
30c87b55 4502 else {
c143ef62 4503 MSR = *rS;
30c87b55
MM
4504 check_masked_interrupts(processor);
4505 }
845ff5a4 4506
c143ef62 45070.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register
54e98699
MM
4508*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4509*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4510*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
4511*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0
c143ef62
MM
4512 if (IS_PROBLEM_STATE(processor))
4513 program_interrupt(processor, cia,
4514 privileged_instruction_program_interrupt);
30c87b55 4515 else {
c143ef62 4516 *rT = MSR;
30c87b55
MM
4517 check_masked_interrupts(processor);
4518 }
c143ef62
MM
4519
4520
4521#
4522# III.4.11.1 Cache Management Instructions
4523#
4524
45250.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate
54e98699
MM
4526*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4527*603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4528*603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0
4529*604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0
845ff5a4
MM
4530 if (IS_PROBLEM_STATE(processor))
4531 program_interrupt(processor, cia,
4532 privileged_instruction_program_interrupt);
4533 else
4534 TRACE(trace_tbd,("Data Cache Block Invalidate\n"));
c143ef62
MM
4535
4536#
4537# III.4.11.2 Segment Register Manipulation Instructions
4538#
4539
45400.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register
54e98699
MM
4541*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4542*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4543*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4544*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4545 if (IS_PROBLEM_STATE(processor))
4546 program_interrupt(processor, cia,
4547 privileged_instruction_program_interrupt);
4548 else
4549 SEGREG(SR) = *rS;
845ff5a4 4550
c143ef62 45510.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect
54e98699
MM
4552*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
4553*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4554*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0
4555*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4556 if (IS_PROBLEM_STATE(processor))
4557 program_interrupt(processor, cia,
4558 privileged_instruction_program_interrupt);
4559 else
4560 SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS;
845ff5a4 4561
c143ef62 45620.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register
54e98699
MM
4563*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4564*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4565*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4566*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4567 if (IS_PROBLEM_STATE(processor))
4568 program_interrupt(processor, cia,
4569 privileged_instruction_program_interrupt);
4570 else
4571 *rT = SEGREG(SR);
845ff5a4 4572
c143ef62 45730.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect
54e98699
MM
4574*601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0
4575*603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4576*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0
4577*604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0
c143ef62
MM
4578 if (IS_PROBLEM_STATE(processor))
4579 program_interrupt(processor, cia,
4580 privileged_instruction_program_interrupt);
4581 else
4582 *rT = SEGREG(EXTRACTED32(*rB, 0, 3));
4583
4584
4585#
4586# III.4.11.3 Lookaside Buffer Management Instructions (Optional)
4587#
4588
45890.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry
845ff5a4 4590
c143ef62
MM
45910.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All
4592
45930.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry
30c87b55
MM
4594 if (IS_PROBLEM_STATE(processor))
4595 program_interrupt(processor, cia,
4596 privileged_instruction_program_interrupt);
4597 else {
4598 int nr = 0;
4599 cpu *proc;
4600 while (1) {
4601 proc = psim_cpu(cpu_system(processor), nr);
4602 if (proc == NULL) break;
4603 cpu_page_tlb_invalidate_entry(proc, *rB);
4604 nr++;
4605 }
4606 }
845ff5a4 4607
c143ef62 46080.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All
30c87b55
MM
4609 if (IS_PROBLEM_STATE(processor))
4610 program_interrupt(processor, cia,
4611 privileged_instruction_program_interrupt);
4612 else {
4613 int nr = 0;
4614 cpu *proc;
4615 while (1) {
4616 proc = psim_cpu(cpu_system(processor), nr);
4617 if (proc == NULL) break;
4618 cpu_page_tlb_invalidate_all(proc);
4619 nr++;
4620 }
4621 }
c143ef62 4622
30c87b55
MM
46230.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize
4624 /* nothing happens here - always in sync */
c143ef62
MM
4625
4626#
4627# III.A.1.2 External Access Instructions
4628#
4629
46300.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
845ff5a4 4631
c143ef62 46320.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
This page took 0.271433 seconds and 4 git commands to generate.