]>
Commit | Line | Data |
---|---|---|
7a3f1944 FB |
1 | /* |
2 | SPARC micro operations | |
3 | ||
4 | Copyright (C) 2003 Thomas M. Ogrisegg <[email protected]> | |
5 | ||
6 | This library is free software; you can redistribute it and/or | |
7 | modify it under the terms of the GNU Lesser General Public | |
8 | License as published by the Free Software Foundation; either | |
9 | version 2 of the License, or (at your option) any later version. | |
10 | ||
11 | This library is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | Lesser General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public | |
17 | License along with this library; if not, write to the Free Software | |
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | */ | |
20 | ||
21 | #include "exec.h" | |
22 | ||
cf495bcf | 23 | /*XXX*/ |
7a3f1944 FB |
24 | #define REGNAME g0 |
25 | #define REG (env->gregs[0]) | |
26 | #include "op_template.h" | |
27 | #define REGNAME g1 | |
28 | #define REG (env->gregs[1]) | |
29 | #include "op_template.h" | |
30 | #define REGNAME g2 | |
31 | #define REG (env->gregs[2]) | |
32 | #include "op_template.h" | |
33 | #define REGNAME g3 | |
34 | #define REG (env->gregs[3]) | |
35 | #include "op_template.h" | |
36 | #define REGNAME g4 | |
37 | #define REG (env->gregs[4]) | |
38 | #include "op_template.h" | |
39 | #define REGNAME g5 | |
40 | #define REG (env->gregs[5]) | |
41 | #include "op_template.h" | |
42 | #define REGNAME g6 | |
43 | #define REG (env->gregs[6]) | |
44 | #include "op_template.h" | |
45 | #define REGNAME g7 | |
46 | #define REG (env->gregs[7]) | |
47 | #include "op_template.h" | |
48 | #define REGNAME i0 | |
49 | #define REG (env->regwptr[16]) | |
50 | #include "op_template.h" | |
51 | #define REGNAME i1 | |
52 | #define REG (env->regwptr[17]) | |
53 | #include "op_template.h" | |
54 | #define REGNAME i2 | |
55 | #define REG (env->regwptr[18]) | |
56 | #include "op_template.h" | |
57 | #define REGNAME i3 | |
58 | #define REG (env->regwptr[19]) | |
59 | #include "op_template.h" | |
60 | #define REGNAME i4 | |
61 | #define REG (env->regwptr[20]) | |
62 | #include "op_template.h" | |
63 | #define REGNAME i5 | |
64 | #define REG (env->regwptr[21]) | |
65 | #include "op_template.h" | |
66 | #define REGNAME i6 | |
67 | #define REG (env->regwptr[22]) | |
68 | #include "op_template.h" | |
69 | #define REGNAME i7 | |
70 | #define REG (env->regwptr[23]) | |
71 | #include "op_template.h" | |
72 | #define REGNAME l0 | |
73 | #define REG (env->regwptr[8]) | |
74 | #include "op_template.h" | |
75 | #define REGNAME l1 | |
76 | #define REG (env->regwptr[9]) | |
77 | #include "op_template.h" | |
78 | #define REGNAME l2 | |
79 | #define REG (env->regwptr[10]) | |
80 | #include "op_template.h" | |
81 | #define REGNAME l3 | |
82 | #define REG (env->regwptr[11]) | |
83 | #include "op_template.h" | |
84 | #define REGNAME l4 | |
85 | #define REG (env->regwptr[12]) | |
86 | #include "op_template.h" | |
87 | #define REGNAME l5 | |
88 | #define REG (env->regwptr[13]) | |
89 | #include "op_template.h" | |
90 | #define REGNAME l6 | |
91 | #define REG (env->regwptr[14]) | |
92 | #include "op_template.h" | |
93 | #define REGNAME l7 | |
94 | #define REG (env->regwptr[15]) | |
95 | #include "op_template.h" | |
96 | #define REGNAME o0 | |
97 | #define REG (env->regwptr[0]) | |
98 | #include "op_template.h" | |
99 | #define REGNAME o1 | |
100 | #define REG (env->regwptr[1]) | |
101 | #include "op_template.h" | |
102 | #define REGNAME o2 | |
103 | #define REG (env->regwptr[2]) | |
104 | #include "op_template.h" | |
105 | #define REGNAME o3 | |
106 | #define REG (env->regwptr[3]) | |
107 | #include "op_template.h" | |
108 | #define REGNAME o4 | |
109 | #define REG (env->regwptr[4]) | |
110 | #include "op_template.h" | |
111 | #define REGNAME o5 | |
112 | #define REG (env->regwptr[5]) | |
113 | #include "op_template.h" | |
114 | #define REGNAME o6 | |
115 | #define REG (env->regwptr[6]) | |
116 | #include "op_template.h" | |
117 | #define REGNAME o7 | |
118 | #define REG (env->regwptr[7]) | |
119 | #include "op_template.h" | |
e8af50a3 FB |
120 | |
121 | #define REGNAME f0 | |
122 | #define REG (env->fpr[0]) | |
123 | #include "fop_template.h" | |
124 | #define REGNAME f1 | |
125 | #define REG (env->fpr[1]) | |
126 | #include "fop_template.h" | |
127 | #define REGNAME f2 | |
128 | #define REG (env->fpr[2]) | |
129 | #include "fop_template.h" | |
130 | #define REGNAME f3 | |
131 | #define REG (env->fpr[3]) | |
132 | #include "fop_template.h" | |
133 | #define REGNAME f4 | |
134 | #define REG (env->fpr[4]) | |
135 | #include "fop_template.h" | |
136 | #define REGNAME f5 | |
137 | #define REG (env->fpr[5]) | |
138 | #include "fop_template.h" | |
139 | #define REGNAME f6 | |
140 | #define REG (env->fpr[6]) | |
141 | #include "fop_template.h" | |
142 | #define REGNAME f7 | |
143 | #define REG (env->fpr[7]) | |
144 | #include "fop_template.h" | |
145 | #define REGNAME f8 | |
146 | #define REG (env->fpr[8]) | |
147 | #include "fop_template.h" | |
148 | #define REGNAME f9 | |
149 | #define REG (env->fpr[9]) | |
150 | #include "fop_template.h" | |
151 | #define REGNAME f10 | |
152 | #define REG (env->fpr[10]) | |
153 | #include "fop_template.h" | |
154 | #define REGNAME f11 | |
155 | #define REG (env->fpr[11]) | |
156 | #include "fop_template.h" | |
157 | #define REGNAME f12 | |
158 | #define REG (env->fpr[12]) | |
159 | #include "fop_template.h" | |
160 | #define REGNAME f13 | |
161 | #define REG (env->fpr[13]) | |
162 | #include "fop_template.h" | |
163 | #define REGNAME f14 | |
164 | #define REG (env->fpr[14]) | |
165 | #include "fop_template.h" | |
166 | #define REGNAME f15 | |
167 | #define REG (env->fpr[15]) | |
168 | #include "fop_template.h" | |
169 | #define REGNAME f16 | |
170 | #define REG (env->fpr[16]) | |
171 | #include "fop_template.h" | |
172 | #define REGNAME f17 | |
173 | #define REG (env->fpr[17]) | |
174 | #include "fop_template.h" | |
175 | #define REGNAME f18 | |
176 | #define REG (env->fpr[18]) | |
177 | #include "fop_template.h" | |
178 | #define REGNAME f19 | |
179 | #define REG (env->fpr[19]) | |
180 | #include "fop_template.h" | |
181 | #define REGNAME f20 | |
182 | #define REG (env->fpr[20]) | |
183 | #include "fop_template.h" | |
184 | #define REGNAME f21 | |
185 | #define REG (env->fpr[21]) | |
186 | #include "fop_template.h" | |
187 | #define REGNAME f22 | |
188 | #define REG (env->fpr[22]) | |
189 | #include "fop_template.h" | |
190 | #define REGNAME f23 | |
191 | #define REG (env->fpr[23]) | |
192 | #include "fop_template.h" | |
193 | #define REGNAME f24 | |
194 | #define REG (env->fpr[24]) | |
195 | #include "fop_template.h" | |
196 | #define REGNAME f25 | |
197 | #define REG (env->fpr[25]) | |
198 | #include "fop_template.h" | |
199 | #define REGNAME f26 | |
200 | #define REG (env->fpr[26]) | |
201 | #include "fop_template.h" | |
202 | #define REGNAME f27 | |
203 | #define REG (env->fpr[27]) | |
204 | #include "fop_template.h" | |
205 | #define REGNAME f28 | |
206 | #define REG (env->fpr[28]) | |
207 | #include "fop_template.h" | |
208 | #define REGNAME f29 | |
209 | #define REG (env->fpr[29]) | |
210 | #include "fop_template.h" | |
211 | #define REGNAME f30 | |
212 | #define REG (env->fpr[30]) | |
213 | #include "fop_template.h" | |
214 | #define REGNAME f31 | |
215 | #define REG (env->fpr[31]) | |
216 | #include "fop_template.h" | |
217 | ||
7a3f1944 FB |
218 | #define EIP (env->pc) |
219 | ||
af7bf89b | 220 | #define FLAG_SET(x) ((env->psr&x)?1:0) |
e8af50a3 | 221 | #define FFLAG_SET(x) ((env->fsr&x)?1:0) |
cf495bcf | 222 | |
7a3f1944 FB |
223 | void OPPROTO op_movl_T0_0(void) |
224 | { | |
cf495bcf | 225 | T0 = 0; |
7a3f1944 FB |
226 | } |
227 | ||
7a3f1944 FB |
228 | void OPPROTO op_movl_T0_im(void) |
229 | { | |
cf495bcf | 230 | T0 = PARAM1; |
7a3f1944 FB |
231 | } |
232 | ||
233 | void OPPROTO op_movl_T1_im(void) | |
234 | { | |
cf495bcf | 235 | T1 = PARAM1; |
7a3f1944 FB |
236 | } |
237 | ||
238 | void OPPROTO op_movl_T2_im(void) | |
239 | { | |
cf495bcf | 240 | T2 = PARAM1; |
7a3f1944 FB |
241 | } |
242 | ||
af7bf89b | 243 | void OPPROTO op_add_T1_T0(void) |
7a3f1944 | 244 | { |
af7bf89b | 245 | T0 += T1; |
7a3f1944 FB |
246 | } |
247 | ||
af7bf89b | 248 | void OPPROTO op_add_T1_T0_cc(void) |
7a3f1944 | 249 | { |
af7bf89b | 250 | target_ulong src1; |
7a3f1944 | 251 | |
af7bf89b FB |
252 | src1 = T0; |
253 | T0 += T1; | |
254 | env->psr = 0; | |
255 | if (!T0) | |
256 | env->psr |= PSR_ZERO; | |
257 | if ((int32_t) T0 < 0) | |
258 | env->psr |= PSR_NEG; | |
259 | if (T0 < src1) | |
260 | env->psr |= PSR_CARRY; | |
261 | if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) | |
262 | env->psr |= PSR_OVF; | |
263 | /* V9 xcc */ | |
264 | FORCE_RET(); | |
7a3f1944 FB |
265 | } |
266 | ||
af7bf89b | 267 | void OPPROTO op_addx_T1_T0(void) |
7a3f1944 | 268 | { |
af7bf89b | 269 | T0 += T1 + FLAG_SET(PSR_CARRY); |
7a3f1944 FB |
270 | } |
271 | ||
af7bf89b | 272 | void OPPROTO op_addx_T1_T0_cc(void) |
7a3f1944 | 273 | { |
af7bf89b FB |
274 | target_ulong src1; |
275 | ||
cf495bcf | 276 | src1 = T0; |
af7bf89b | 277 | T0 += T1 + FLAG_SET(PSR_CARRY); |
cf495bcf FB |
278 | env->psr = 0; |
279 | if (!T0) | |
280 | env->psr |= PSR_ZERO; | |
af7bf89b | 281 | if ((int32_t) T0 < 0) |
cf495bcf FB |
282 | env->psr |= PSR_NEG; |
283 | if (T0 < src1) | |
284 | env->psr |= PSR_CARRY; | |
285 | if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) | |
286 | env->psr |= PSR_OVF; | |
af7bf89b | 287 | /* V9 xcc */ |
cf495bcf | 288 | FORCE_RET(); |
7a3f1944 FB |
289 | } |
290 | ||
cf495bcf | 291 | void OPPROTO op_sub_T1_T0(void) |
7a3f1944 | 292 | { |
cf495bcf | 293 | T0 -= T1; |
7a3f1944 FB |
294 | } |
295 | ||
cf495bcf | 296 | void OPPROTO op_sub_T1_T0_cc(void) |
7a3f1944 | 297 | { |
af7bf89b | 298 | target_ulong src1; |
cf495bcf FB |
299 | |
300 | src1 = T0; | |
301 | T0 -= T1; | |
302 | env->psr = 0; | |
303 | if (!T0) | |
304 | env->psr |= PSR_ZERO; | |
af7bf89b | 305 | if ((int32_t) T0 < 0) |
cf495bcf FB |
306 | env->psr |= PSR_NEG; |
307 | if (src1 < T1) | |
308 | env->psr |= PSR_CARRY; | |
309 | if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) | |
310 | env->psr |= PSR_OVF; | |
af7bf89b FB |
311 | /* V9 xcc */ |
312 | FORCE_RET(); | |
313 | } | |
314 | ||
315 | void OPPROTO op_subx_T1_T0(void) | |
316 | { | |
317 | T0 -= T1 + FLAG_SET(PSR_CARRY); | |
318 | } | |
319 | ||
320 | void OPPROTO op_subx_T1_T0_cc(void) | |
321 | { | |
322 | target_ulong src1; | |
323 | ||
324 | src1 = T0; | |
325 | T0 -= T1 + FLAG_SET(PSR_CARRY); | |
326 | env->psr = 0; | |
327 | if (!T0) | |
328 | env->psr |= PSR_ZERO; | |
329 | if ((int32_t) T0 < 0) | |
330 | env->psr |= PSR_NEG; | |
331 | if (src1 < T1) | |
332 | env->psr |= PSR_CARRY; | |
333 | if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) | |
334 | env->psr |= PSR_OVF; | |
335 | /* V9 xcc */ | |
cf495bcf | 336 | FORCE_RET(); |
7a3f1944 FB |
337 | } |
338 | ||
cf495bcf | 339 | void OPPROTO op_and_T1_T0(void) |
7a3f1944 | 340 | { |
cf495bcf | 341 | T0 &= T1; |
7a3f1944 FB |
342 | } |
343 | ||
cf495bcf | 344 | void OPPROTO op_or_T1_T0(void) |
7a3f1944 | 345 | { |
cf495bcf | 346 | T0 |= T1; |
7a3f1944 FB |
347 | } |
348 | ||
cf495bcf | 349 | void OPPROTO op_xor_T1_T0(void) |
7a3f1944 | 350 | { |
cf495bcf | 351 | T0 ^= T1; |
7a3f1944 FB |
352 | } |
353 | ||
cf495bcf | 354 | void OPPROTO op_andn_T1_T0(void) |
7a3f1944 | 355 | { |
cf495bcf | 356 | T0 &= ~T1; |
7a3f1944 FB |
357 | } |
358 | ||
cf495bcf | 359 | void OPPROTO op_orn_T1_T0(void) |
7a3f1944 | 360 | { |
cf495bcf | 361 | T0 |= ~T1; |
7a3f1944 FB |
362 | } |
363 | ||
cf495bcf | 364 | void OPPROTO op_xnor_T1_T0(void) |
7a3f1944 | 365 | { |
cf495bcf | 366 | T0 ^= ~T1; |
7a3f1944 FB |
367 | } |
368 | ||
cf495bcf | 369 | void OPPROTO op_umul_T1_T0(void) |
7a3f1944 | 370 | { |
cf495bcf | 371 | uint64_t res; |
af7bf89b | 372 | res = (uint64_t) T0 * (uint64_t) T1; |
cf495bcf FB |
373 | T0 = res & 0xffffffff; |
374 | env->y = res >> 32; | |
7a3f1944 FB |
375 | } |
376 | ||
cf495bcf | 377 | void OPPROTO op_smul_T1_T0(void) |
7a3f1944 | 378 | { |
cf495bcf FB |
379 | uint64_t res; |
380 | res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1); | |
381 | T0 = res & 0xffffffff; | |
382 | env->y = res >> 32; | |
7a3f1944 FB |
383 | } |
384 | ||
cf495bcf | 385 | void OPPROTO op_mulscc_T1_T0(void) |
7a3f1944 | 386 | { |
af7bf89b FB |
387 | unsigned int b1, N, V, b2; |
388 | target_ulong src1; | |
389 | ||
4e8b5da2 | 390 | N = FLAG_SET(PSR_NEG); |
cf495bcf | 391 | V = FLAG_SET(PSR_OVF); |
4e8b5da2 | 392 | b1 = N ^ V; |
cf495bcf FB |
393 | b2 = T0 & 1; |
394 | T0 = (b1 << 31) | (T0 >> 1); | |
395 | if (!(env->y & 1)) | |
396 | T1 = 0; | |
397 | /* do addition and update flags */ | |
398 | src1 = T0; | |
399 | T0 += T1; | |
400 | env->psr = 0; | |
401 | if (!T0) | |
402 | env->psr |= PSR_ZERO; | |
af7bf89b | 403 | if ((int32_t) T0 < 0) |
cf495bcf FB |
404 | env->psr |= PSR_NEG; |
405 | if (T0 < src1) | |
406 | env->psr |= PSR_CARRY; | |
407 | if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) | |
408 | env->psr |= PSR_OVF; | |
409 | env->y = (b2 << 31) | (env->y >> 1); | |
410 | FORCE_RET(); | |
411 | } | |
412 | ||
413 | void OPPROTO op_udiv_T1_T0(void) | |
414 | { | |
415 | uint64_t x0; | |
416 | uint32_t x1; | |
417 | ||
418 | x0 = T0 | ((uint64_t) (env->y) << 32); | |
419 | x1 = T1; | |
420 | x0 = x0 / x1; | |
421 | if (x0 > 0xffffffff) { | |
422 | T0 = 0xffffffff; | |
423 | T1 = 1; | |
424 | } else { | |
425 | T0 = x0; | |
426 | T1 = 0; | |
427 | } | |
428 | FORCE_RET(); | |
7a3f1944 FB |
429 | } |
430 | ||
cf495bcf | 431 | void OPPROTO op_sdiv_T1_T0(void) |
7a3f1944 | 432 | { |
cf495bcf FB |
433 | int64_t x0; |
434 | int32_t x1; | |
435 | ||
af7bf89b | 436 | x0 = T0 | ((int64_t) (env->y) << 32); |
cf495bcf FB |
437 | x1 = T1; |
438 | x0 = x0 / x1; | |
439 | if ((int32_t) x0 != x0) { | |
af7bf89b | 440 | T0 = x0 < 0? 0x80000000: 0x7fffffff; |
cf495bcf FB |
441 | T1 = 1; |
442 | } else { | |
443 | T0 = x0; | |
444 | T1 = 0; | |
445 | } | |
446 | FORCE_RET(); | |
7a3f1944 FB |
447 | } |
448 | ||
cf495bcf | 449 | void OPPROTO op_div_cc(void) |
7a3f1944 | 450 | { |
cf495bcf FB |
451 | env->psr = 0; |
452 | if (!T0) | |
453 | env->psr |= PSR_ZERO; | |
af7bf89b | 454 | if ((int32_t) T0 < 0) |
cf495bcf FB |
455 | env->psr |= PSR_NEG; |
456 | if (T1) | |
457 | env->psr |= PSR_OVF; | |
af7bf89b | 458 | /* V9 xcc */ |
cf495bcf | 459 | FORCE_RET(); |
7a3f1944 FB |
460 | } |
461 | ||
cf495bcf | 462 | void OPPROTO op_logic_T0_cc(void) |
7a3f1944 | 463 | { |
cf495bcf FB |
464 | env->psr = 0; |
465 | if (!T0) | |
466 | env->psr |= PSR_ZERO; | |
af7bf89b | 467 | if ((int32_t) T0 < 0) |
cf495bcf | 468 | env->psr |= PSR_NEG; |
af7bf89b | 469 | /* V9 xcc */ |
cf495bcf | 470 | FORCE_RET(); |
7a3f1944 FB |
471 | } |
472 | ||
cf495bcf | 473 | void OPPROTO op_sll(void) |
7a3f1944 | 474 | { |
cf495bcf | 475 | T0 <<= T1; |
7a3f1944 FB |
476 | } |
477 | ||
cf495bcf | 478 | void OPPROTO op_srl(void) |
7a3f1944 | 479 | { |
cf495bcf | 480 | T0 >>= T1; |
7a3f1944 FB |
481 | } |
482 | ||
cf495bcf | 483 | void OPPROTO op_sra(void) |
7a3f1944 | 484 | { |
cf495bcf | 485 | T0 = ((int32_t) T0) >> T1; |
7a3f1944 FB |
486 | } |
487 | ||
e8af50a3 FB |
488 | /* Load and store */ |
489 | #define MEMSUFFIX _raw | |
490 | #include "op_mem.h" | |
491 | #if !defined(CONFIG_USER_ONLY) | |
492 | #define MEMSUFFIX _user | |
493 | #include "op_mem.h" | |
494 | ||
495 | #define MEMSUFFIX _kernel | |
496 | #include "op_mem.h" | |
497 | #endif | |
e8af50a3 FB |
498 | |
499 | void OPPROTO op_ldfsr(void) | |
500 | { | |
501 | env->fsr = *((uint32_t *) &FT0); | |
8d5f07fa | 502 | helper_ldfsr(); |
e8af50a3 FB |
503 | } |
504 | ||
505 | void OPPROTO op_stfsr(void) | |
506 | { | |
507 | *((uint32_t *) &FT0) = env->fsr; | |
e8af50a3 FB |
508 | } |
509 | ||
cf495bcf | 510 | void OPPROTO op_wry(void) |
7a3f1944 | 511 | { |
cf495bcf | 512 | env->y = T0; |
7a3f1944 FB |
513 | } |
514 | ||
cf495bcf | 515 | void OPPROTO op_rdy(void) |
7a3f1944 | 516 | { |
cf495bcf | 517 | T0 = env->y; |
7a3f1944 FB |
518 | } |
519 | ||
e8af50a3 | 520 | void OPPROTO op_rdwim(void) |
cf495bcf | 521 | { |
e8af50a3 FB |
522 | T0 = env->wim; |
523 | } | |
524 | ||
525 | void OPPROTO op_wrwim(void) | |
526 | { | |
527 | env->wim = T0; | |
528 | FORCE_RET(); | |
529 | } | |
530 | ||
531 | void OPPROTO op_rdpsr(void) | |
532 | { | |
af7bf89b | 533 | do_rdpsr(); |
e8af50a3 FB |
534 | } |
535 | ||
536 | void OPPROTO op_wrpsr(void) | |
537 | { | |
af7bf89b | 538 | do_wrpsr(); |
e8af50a3 FB |
539 | FORCE_RET(); |
540 | } | |
541 | ||
542 | void OPPROTO op_rdtbr(void) | |
543 | { | |
544 | T0 = env->tbr; | |
545 | } | |
cf495bcf | 546 | |
e8af50a3 | 547 | void OPPROTO op_wrtbr(void) |
7a3f1944 | 548 | { |
e8af50a3 FB |
549 | env->tbr = T0; |
550 | FORCE_RET(); | |
7a3f1944 FB |
551 | } |
552 | ||
e8af50a3 | 553 | void OPPROTO op_rett(void) |
cf495bcf | 554 | { |
e8af50a3 FB |
555 | helper_rett(); |
556 | FORCE_RET(); | |
cf495bcf | 557 | } |
7a3f1944 | 558 | |
cf495bcf FB |
559 | /* XXX: use another pointer for %iN registers to avoid slow wrapping |
560 | handling ? */ | |
561 | void OPPROTO op_save(void) | |
7a3f1944 | 562 | { |
af7bf89b | 563 | uint32_t cwp; |
cf495bcf FB |
564 | cwp = (env->cwp - 1) & (NWINDOWS - 1); |
565 | if (env->wim & (1 << cwp)) { | |
566 | raise_exception(TT_WIN_OVF); | |
567 | } | |
568 | set_cwp(cwp); | |
569 | FORCE_RET(); | |
7a3f1944 FB |
570 | } |
571 | ||
cf495bcf | 572 | void OPPROTO op_restore(void) |
7a3f1944 | 573 | { |
af7bf89b | 574 | uint32_t cwp; |
cf495bcf FB |
575 | cwp = (env->cwp + 1) & (NWINDOWS - 1); |
576 | if (env->wim & (1 << cwp)) { | |
577 | raise_exception(TT_WIN_UNF); | |
578 | } | |
579 | set_cwp(cwp); | |
580 | FORCE_RET(); | |
7a3f1944 FB |
581 | } |
582 | ||
cf495bcf | 583 | void OPPROTO op_exception(void) |
7a3f1944 | 584 | { |
cf495bcf FB |
585 | env->exception_index = PARAM1; |
586 | cpu_loop_exit(); | |
7a3f1944 FB |
587 | } |
588 | ||
cf495bcf | 589 | void OPPROTO op_trap_T0(void) |
7a3f1944 | 590 | { |
cf495bcf FB |
591 | env->exception_index = TT_TRAP + (T0 & 0x7f); |
592 | cpu_loop_exit(); | |
7a3f1944 FB |
593 | } |
594 | ||
cf495bcf | 595 | void OPPROTO op_trapcc_T0(void) |
7a3f1944 | 596 | { |
cf495bcf FB |
597 | if (T2) { |
598 | env->exception_index = TT_TRAP + (T0 & 0x7f); | |
599 | cpu_loop_exit(); | |
600 | } | |
601 | FORCE_RET(); | |
7a3f1944 FB |
602 | } |
603 | ||
e80cfcfc FB |
604 | void OPPROTO op_trap_ifnofpu(void) |
605 | { | |
606 | if (!env->psref) { | |
607 | env->exception_index = TT_NFPU_INSN; | |
608 | cpu_loop_exit(); | |
609 | } | |
610 | FORCE_RET(); | |
611 | } | |
612 | ||
613 | void OPPROTO op_fpexception_im(void) | |
e8af50a3 | 614 | { |
e80cfcfc FB |
615 | env->exception_index = TT_FP_EXCP; |
616 | env->fsr &= ~FSR_FTT_MASK; | |
617 | env->fsr |= PARAM1; | |
e8af50a3 | 618 | cpu_loop_exit(); |
e80cfcfc FB |
619 | FORCE_RET(); |
620 | } | |
621 | ||
622 | void OPPROTO op_debug(void) | |
623 | { | |
624 | helper_debug(); | |
e8af50a3 FB |
625 | } |
626 | ||
cf495bcf | 627 | void OPPROTO op_exit_tb(void) |
7a3f1944 | 628 | { |
cf495bcf | 629 | EXIT_TB(); |
7a3f1944 FB |
630 | } |
631 | ||
cf495bcf | 632 | void OPPROTO op_eval_be(void) |
7a3f1944 | 633 | { |
af7bf89b | 634 | T2 = FLAG_SET(PSR_ZERO); |
7a3f1944 FB |
635 | } |
636 | ||
cf495bcf | 637 | void OPPROTO op_eval_ble(void) |
7a3f1944 | 638 | { |
af7bf89b | 639 | target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
612b477d | 640 | |
cf495bcf | 641 | T2 = Z | (N ^ V); |
7a3f1944 FB |
642 | } |
643 | ||
cf495bcf | 644 | void OPPROTO op_eval_bl(void) |
7a3f1944 | 645 | { |
af7bf89b | 646 | target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
612b477d | 647 | |
cf495bcf | 648 | T2 = N ^ V; |
7a3f1944 FB |
649 | } |
650 | ||
cf495bcf | 651 | void OPPROTO op_eval_bleu(void) |
7a3f1944 | 652 | { |
af7bf89b | 653 | target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); |
612b477d | 654 | |
cf495bcf | 655 | T2 = C | Z; |
7a3f1944 FB |
656 | } |
657 | ||
cf495bcf | 658 | void OPPROTO op_eval_bcs(void) |
7a3f1944 | 659 | { |
af7bf89b | 660 | T2 = FLAG_SET(PSR_CARRY); |
7a3f1944 FB |
661 | } |
662 | ||
cf495bcf | 663 | void OPPROTO op_eval_bvs(void) |
7a3f1944 | 664 | { |
af7bf89b | 665 | T2 = FLAG_SET(PSR_OVF); |
7a3f1944 FB |
666 | } |
667 | ||
cf495bcf | 668 | void OPPROTO op_eval_bneg(void) |
7a3f1944 | 669 | { |
af7bf89b | 670 | T2 = FLAG_SET(PSR_NEG); |
7a3f1944 FB |
671 | } |
672 | ||
cf495bcf | 673 | void OPPROTO op_eval_bne(void) |
7a3f1944 | 674 | { |
af7bf89b | 675 | T2 = !FLAG_SET(PSR_ZERO); |
7a3f1944 FB |
676 | } |
677 | ||
cf495bcf | 678 | void OPPROTO op_eval_bg(void) |
7a3f1944 | 679 | { |
af7bf89b | 680 | target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
612b477d | 681 | |
cf495bcf | 682 | T2 = !(Z | (N ^ V)); |
7a3f1944 FB |
683 | } |
684 | ||
cf495bcf | 685 | void OPPROTO op_eval_bge(void) |
7a3f1944 | 686 | { |
af7bf89b | 687 | target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
612b477d | 688 | |
cf495bcf | 689 | T2 = !(N ^ V); |
7a3f1944 FB |
690 | } |
691 | ||
cf495bcf | 692 | void OPPROTO op_eval_bgu(void) |
7a3f1944 | 693 | { |
af7bf89b | 694 | target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); |
612b477d | 695 | |
cf495bcf | 696 | T2 = !(C | Z); |
7a3f1944 FB |
697 | } |
698 | ||
cf495bcf | 699 | void OPPROTO op_eval_bcc(void) |
7a3f1944 | 700 | { |
af7bf89b | 701 | T2 = !FLAG_SET(PSR_CARRY); |
7a3f1944 FB |
702 | } |
703 | ||
cf495bcf FB |
704 | void OPPROTO op_eval_bpos(void) |
705 | { | |
af7bf89b | 706 | T2 = !FLAG_SET(PSR_NEG); |
cf495bcf FB |
707 | } |
708 | ||
709 | void OPPROTO op_eval_bvc(void) | |
710 | { | |
af7bf89b | 711 | T2 = !FLAG_SET(PSR_OVF); |
cf495bcf FB |
712 | } |
713 | ||
e8af50a3 FB |
714 | /* FCC1:FCC0: 0 =, 1 <, 2 >, 3 u */ |
715 | ||
716 | void OPPROTO op_eval_fbne(void) | |
717 | { | |
718 | // !0 | |
719 | T2 = (env->fsr & (FSR_FCC1 | FSR_FCC0)); /* L or G or U */ | |
720 | } | |
721 | ||
722 | void OPPROTO op_eval_fblg(void) | |
723 | { | |
724 | // 1 or 2 | |
725 | T2 = FFLAG_SET(FSR_FCC0) ^ FFLAG_SET(FSR_FCC1); | |
726 | } | |
727 | ||
728 | void OPPROTO op_eval_fbul(void) | |
729 | { | |
730 | // 1 or 3 | |
731 | T2 = FFLAG_SET(FSR_FCC0); | |
732 | } | |
733 | ||
734 | void OPPROTO op_eval_fbl(void) | |
735 | { | |
736 | // 1 | |
737 | T2 = FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); | |
738 | } | |
739 | ||
740 | void OPPROTO op_eval_fbug(void) | |
741 | { | |
742 | // 2 or 3 | |
743 | T2 = FFLAG_SET(FSR_FCC1); | |
744 | } | |
745 | ||
746 | void OPPROTO op_eval_fbg(void) | |
747 | { | |
748 | // 2 | |
749 | T2 = !FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); | |
750 | } | |
751 | ||
752 | void OPPROTO op_eval_fbu(void) | |
753 | { | |
754 | // 3 | |
755 | T2 = FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); | |
756 | } | |
757 | ||
758 | void OPPROTO op_eval_fbe(void) | |
759 | { | |
760 | // 0 | |
761 | T2 = !FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); | |
762 | } | |
763 | ||
764 | void OPPROTO op_eval_fbue(void) | |
765 | { | |
766 | // 0 or 3 | |
767 | T2 = !(FFLAG_SET(FSR_FCC1) ^ FFLAG_SET(FSR_FCC0)); | |
6eea2b1b | 768 | FORCE_RET(); |
e8af50a3 FB |
769 | } |
770 | ||
771 | void OPPROTO op_eval_fbge(void) | |
772 | { | |
773 | // 0 or 2 | |
774 | T2 = !FFLAG_SET(FSR_FCC0); | |
775 | } | |
776 | ||
777 | void OPPROTO op_eval_fbuge(void) | |
778 | { | |
779 | // !1 | |
780 | T2 = !(FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1)); | |
781 | } | |
782 | ||
783 | void OPPROTO op_eval_fble(void) | |
784 | { | |
785 | // 0 or 1 | |
786 | T2 = !FFLAG_SET(FSR_FCC1); | |
787 | } | |
788 | ||
789 | void OPPROTO op_eval_fbule(void) | |
790 | { | |
791 | // !2 | |
792 | T2 = !(!FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); | |
793 | } | |
794 | ||
795 | void OPPROTO op_eval_fbo(void) | |
796 | { | |
797 | // !3 | |
798 | T2 = !(FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); | |
799 | } | |
800 | ||
cf495bcf FB |
801 | void OPPROTO op_jmp_im(void) |
802 | { | |
803 | env->pc = PARAM1; | |
804 | } | |
805 | ||
806 | void OPPROTO op_movl_npc_im(void) | |
807 | { | |
808 | env->npc = PARAM1; | |
809 | } | |
7a3f1944 | 810 | |
cf495bcf | 811 | void OPPROTO op_movl_npc_T0(void) |
7a3f1944 | 812 | { |
cf495bcf | 813 | env->npc = T0; |
7a3f1944 FB |
814 | } |
815 | ||
0bee699e FB |
816 | void OPPROTO op_mov_pc_npc(void) |
817 | { | |
818 | env->pc = env->npc; | |
819 | } | |
820 | ||
cf495bcf | 821 | void OPPROTO op_next_insn(void) |
7a3f1944 | 822 | { |
cf495bcf FB |
823 | env->pc = env->npc; |
824 | env->npc = env->npc + 4; | |
7a3f1944 FB |
825 | } |
826 | ||
72cbca10 FB |
827 | void OPPROTO op_branch(void) |
828 | { | |
829 | env->npc = PARAM3; /* XXX: optimize */ | |
830 | JUMP_TB(op_branch, PARAM1, 0, PARAM2); | |
831 | } | |
832 | ||
833 | void OPPROTO op_branch2(void) | |
7a3f1944 | 834 | { |
cf495bcf | 835 | if (T2) { |
72cbca10 FB |
836 | env->npc = PARAM2 + 4; |
837 | JUMP_TB(op_branch2, PARAM1, 0, PARAM2); | |
cf495bcf | 838 | } else { |
72cbca10 FB |
839 | env->npc = PARAM3 + 4; |
840 | JUMP_TB(op_branch2, PARAM1, 1, PARAM3); | |
841 | } | |
842 | FORCE_RET(); | |
843 | } | |
844 | ||
845 | void OPPROTO op_branch_a(void) | |
846 | { | |
847 | if (T2) { | |
848 | env->npc = PARAM2; /* XXX: optimize */ | |
af7bf89b | 849 | JUMP_TB(op_branch_a, PARAM1, 0, PARAM3); |
72cbca10 FB |
850 | } else { |
851 | env->npc = PARAM3 + 8; /* XXX: optimize */ | |
af7bf89b | 852 | JUMP_TB(op_branch_a, PARAM1, 1, PARAM3 + 4); |
cf495bcf FB |
853 | } |
854 | FORCE_RET(); | |
7a3f1944 FB |
855 | } |
856 | ||
72cbca10 | 857 | void OPPROTO op_generic_branch(void) |
7a3f1944 | 858 | { |
cf495bcf | 859 | if (T2) { |
cf495bcf FB |
860 | env->npc = PARAM1; |
861 | } else { | |
72cbca10 | 862 | env->npc = PARAM2; |
cf495bcf FB |
863 | } |
864 | FORCE_RET(); | |
7a3f1944 | 865 | } |
72cbca10 | 866 | |
658138bc FB |
867 | void OPPROTO op_flush_T0(void) |
868 | { | |
869 | helper_flush(T0); | |
870 | } | |
e8af50a3 FB |
871 | |
872 | void OPPROTO op_fnegs(void) | |
873 | { | |
874 | FT0 = -FT1; | |
875 | } | |
876 | ||
877 | void OPPROTO op_fabss(void) | |
878 | { | |
879 | do_fabss(); | |
880 | } | |
881 | ||
882 | void OPPROTO op_fsqrts(void) | |
883 | { | |
884 | do_fsqrts(); | |
885 | } | |
886 | ||
887 | void OPPROTO op_fsqrtd(void) | |
888 | { | |
889 | do_fsqrtd(); | |
890 | } | |
891 | ||
892 | void OPPROTO op_fmuls(void) | |
893 | { | |
894 | FT0 *= FT1; | |
895 | } | |
896 | ||
897 | void OPPROTO op_fmuld(void) | |
898 | { | |
899 | DT0 *= DT1; | |
900 | } | |
901 | ||
902 | void OPPROTO op_fsmuld(void) | |
903 | { | |
904 | DT0 = FT0 * FT1; | |
905 | } | |
906 | ||
907 | void OPPROTO op_fadds(void) | |
908 | { | |
909 | FT0 += FT1; | |
910 | } | |
911 | ||
912 | void OPPROTO op_faddd(void) | |
913 | { | |
914 | DT0 += DT1; | |
915 | } | |
916 | ||
917 | void OPPROTO op_fsubs(void) | |
918 | { | |
919 | FT0 -= FT1; | |
920 | } | |
921 | ||
922 | void OPPROTO op_fsubd(void) | |
923 | { | |
924 | DT0 -= DT1; | |
925 | } | |
926 | ||
927 | void OPPROTO op_fdivs(void) | |
928 | { | |
929 | FT0 /= FT1; | |
930 | } | |
931 | ||
932 | void OPPROTO op_fdivd(void) | |
933 | { | |
934 | DT0 /= DT1; | |
935 | } | |
936 | ||
937 | void OPPROTO op_fcmps(void) | |
938 | { | |
939 | do_fcmps(); | |
940 | } | |
941 | ||
942 | void OPPROTO op_fcmpd(void) | |
943 | { | |
944 | do_fcmpd(); | |
945 | } | |
946 | ||
a0c4cb4a | 947 | #ifdef USE_INT_TO_FLOAT_HELPERS |
e8af50a3 FB |
948 | void OPPROTO op_fitos(void) |
949 | { | |
a0c4cb4a | 950 | do_fitos(); |
e8af50a3 FB |
951 | } |
952 | ||
a0c4cb4a | 953 | void OPPROTO op_fitod(void) |
e8af50a3 | 954 | { |
a0c4cb4a FB |
955 | do_fitod(); |
956 | } | |
957 | #else | |
958 | void OPPROTO op_fitos(void) | |
959 | { | |
960 | FT0 = (float) *((int32_t *)&FT1); | |
e8af50a3 FB |
961 | } |
962 | ||
963 | void OPPROTO op_fitod(void) | |
964 | { | |
965 | DT0 = (double) *((int32_t *)&FT1); | |
966 | } | |
a0c4cb4a FB |
967 | #endif |
968 | ||
969 | void OPPROTO op_fdtos(void) | |
970 | { | |
971 | FT0 = (float) DT1; | |
972 | } | |
e8af50a3 FB |
973 | |
974 | void OPPROTO op_fstod(void) | |
975 | { | |
976 | DT0 = (double) FT1; | |
977 | } | |
978 | ||
979 | void OPPROTO op_fstoi(void) | |
980 | { | |
981 | *((int32_t *)&FT0) = (int32_t) FT1; | |
982 | } | |
983 | ||
984 | void OPPROTO op_fdtoi(void) | |
985 | { | |
986 | *((int32_t *)&FT0) = (int32_t) DT1; | |
987 | } | |
988 | ||
989 | void OPPROTO op_ld_asi() | |
990 | { | |
991 | helper_ld_asi(PARAM1, PARAM2, PARAM3); | |
992 | } | |
993 | ||
994 | void OPPROTO op_st_asi() | |
995 | { | |
996 | helper_st_asi(PARAM1, PARAM2, PARAM3); | |
997 | } | |
998 |