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