]> Git Repo - qemu.git/blame - target-sparc/op.c
ds1225y nvram: Fix some bugs
[qemu.git] / target-sparc / op.c
CommitLineData
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"
1a2fb1c0 22#include "helper.h"
e8af50a3
FB
23
24#define REGNAME f0
25#define REG (env->fpr[0])
26#include "fop_template.h"
27#define REGNAME f1
28#define REG (env->fpr[1])
29#include "fop_template.h"
30#define REGNAME f2
31#define REG (env->fpr[2])
32#include "fop_template.h"
33#define REGNAME f3
34#define REG (env->fpr[3])
35#include "fop_template.h"
36#define REGNAME f4
37#define REG (env->fpr[4])
38#include "fop_template.h"
39#define REGNAME f5
40#define REG (env->fpr[5])
41#include "fop_template.h"
42#define REGNAME f6
43#define REG (env->fpr[6])
44#include "fop_template.h"
45#define REGNAME f7
46#define REG (env->fpr[7])
47#include "fop_template.h"
48#define REGNAME f8
49#define REG (env->fpr[8])
50#include "fop_template.h"
51#define REGNAME f9
52#define REG (env->fpr[9])
53#include "fop_template.h"
54#define REGNAME f10
55#define REG (env->fpr[10])
56#include "fop_template.h"
57#define REGNAME f11
58#define REG (env->fpr[11])
59#include "fop_template.h"
60#define REGNAME f12
61#define REG (env->fpr[12])
62#include "fop_template.h"
63#define REGNAME f13
64#define REG (env->fpr[13])
65#include "fop_template.h"
66#define REGNAME f14
67#define REG (env->fpr[14])
68#include "fop_template.h"
69#define REGNAME f15
70#define REG (env->fpr[15])
71#include "fop_template.h"
72#define REGNAME f16
73#define REG (env->fpr[16])
74#include "fop_template.h"
75#define REGNAME f17
76#define REG (env->fpr[17])
77#include "fop_template.h"
78#define REGNAME f18
79#define REG (env->fpr[18])
80#include "fop_template.h"
81#define REGNAME f19
82#define REG (env->fpr[19])
83#include "fop_template.h"
84#define REGNAME f20
85#define REG (env->fpr[20])
86#include "fop_template.h"
87#define REGNAME f21
88#define REG (env->fpr[21])
89#include "fop_template.h"
90#define REGNAME f22
91#define REG (env->fpr[22])
92#include "fop_template.h"
93#define REGNAME f23
94#define REG (env->fpr[23])
95#include "fop_template.h"
96#define REGNAME f24
97#define REG (env->fpr[24])
98#include "fop_template.h"
99#define REGNAME f25
100#define REG (env->fpr[25])
101#include "fop_template.h"
102#define REGNAME f26
103#define REG (env->fpr[26])
104#include "fop_template.h"
105#define REGNAME f27
106#define REG (env->fpr[27])
107#include "fop_template.h"
108#define REGNAME f28
109#define REG (env->fpr[28])
110#include "fop_template.h"
111#define REGNAME f29
112#define REG (env->fpr[29])
113#include "fop_template.h"
114#define REGNAME f30
115#define REG (env->fpr[30])
116#include "fop_template.h"
117#define REGNAME f31
118#define REG (env->fpr[31])
119#include "fop_template.h"
120
3475187d
FB
121#ifdef TARGET_SPARC64
122#define REGNAME f32
123#define REG (env->fpr[32])
124#include "fop_template.h"
125#define REGNAME f34
126#define REG (env->fpr[34])
127#include "fop_template.h"
128#define REGNAME f36
129#define REG (env->fpr[36])
130#include "fop_template.h"
131#define REGNAME f38
132#define REG (env->fpr[38])
133#include "fop_template.h"
134#define REGNAME f40
135#define REG (env->fpr[40])
136#include "fop_template.h"
137#define REGNAME f42
138#define REG (env->fpr[42])
139#include "fop_template.h"
140#define REGNAME f44
141#define REG (env->fpr[44])
142#include "fop_template.h"
143#define REGNAME f46
144#define REG (env->fpr[46])
145#include "fop_template.h"
146#define REGNAME f48
147#define REG (env->fpr[47])
148#include "fop_template.h"
149#define REGNAME f50
150#define REG (env->fpr[50])
151#include "fop_template.h"
152#define REGNAME f52
153#define REG (env->fpr[52])
154#include "fop_template.h"
155#define REGNAME f54
156#define REG (env->fpr[54])
157#include "fop_template.h"
158#define REGNAME f56
159#define REG (env->fpr[56])
160#include "fop_template.h"
161#define REGNAME f58
162#define REG (env->fpr[58])
163#include "fop_template.h"
164#define REGNAME f60
165#define REG (env->fpr[60])
166#include "fop_template.h"
167#define REGNAME f62
168#define REG (env->fpr[62])
169#include "fop_template.h"
170#endif
171
af7bf89b 172#define FLAG_SET(x) ((env->psr&x)?1:0)
cf495bcf 173
af7bf89b 174void OPPROTO op_add_T1_T0_cc(void)
7a3f1944 175{
af7bf89b 176 target_ulong src1;
7a3f1944 177
af7bf89b
FB
178 src1 = T0;
179 T0 += T1;
180 env->psr = 0;
3475187d
FB
181#ifdef TARGET_SPARC64
182 if (!(T0 & 0xffffffff))
0f8a249a 183 env->psr |= PSR_ZERO;
3475187d 184 if ((int32_t) T0 < 0)
0f8a249a 185 env->psr |= PSR_NEG;
bb3911a6 186 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
0f8a249a 187 env->psr |= PSR_CARRY;
3475187d 188 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
0f8a249a
BS
189 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
190 env->psr |= PSR_OVF;
3475187d
FB
191
192 env->xcc = 0;
193 if (!T0)
0f8a249a 194 env->xcc |= PSR_ZERO;
3475187d 195 if ((int64_t) T0 < 0)
0f8a249a 196 env->xcc |= PSR_NEG;
3475187d 197 if (T0 < src1)
0f8a249a 198 env->xcc |= PSR_CARRY;
3475187d 199 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
0f8a249a 200 env->xcc |= PSR_OVF;
3475187d 201#else
af7bf89b 202 if (!T0)
0f8a249a 203 env->psr |= PSR_ZERO;
af7bf89b 204 if ((int32_t) T0 < 0)
0f8a249a 205 env->psr |= PSR_NEG;
af7bf89b 206 if (T0 < src1)
0f8a249a 207 env->psr |= PSR_CARRY;
af7bf89b 208 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
0f8a249a 209 env->psr |= PSR_OVF;
3475187d 210#endif
af7bf89b 211 FORCE_RET();
7a3f1944
FB
212}
213
af7bf89b 214void OPPROTO op_addx_T1_T0_cc(void)
7a3f1944 215{
af7bf89b 216 target_ulong src1;
cf495bcf 217 src1 = T0;
b854608e
FB
218 if (FLAG_SET(PSR_CARRY))
219 {
220 T0 += T1 + 1;
221 env->psr = 0;
222#ifdef TARGET_SPARC64
223 if ((T0 & 0xffffffff) <= (src1 & 0xffffffff))
224 env->psr |= PSR_CARRY;
225 env->xcc = 0;
226 if (T0 <= src1)
227 env->xcc |= PSR_CARRY;
228#else
229 if (T0 <= src1)
230 env->psr |= PSR_CARRY;
231#endif
232 }
233 else
234 {
235 T0 += T1;
236 env->psr = 0;
237#ifdef TARGET_SPARC64
238 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
239 env->psr |= PSR_CARRY;
240 env->xcc = 0;
241 if (T0 < src1)
242 env->xcc |= PSR_CARRY;
243#else
244 if (T0 < src1)
245 env->psr |= PSR_CARRY;
246#endif
247 }
3475187d
FB
248#ifdef TARGET_SPARC64
249 if (!(T0 & 0xffffffff))
0f8a249a 250 env->psr |= PSR_ZERO;
3475187d 251 if ((int32_t) T0 < 0)
0f8a249a 252 env->psr |= PSR_NEG;
3475187d 253 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
0f8a249a
BS
254 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
255 env->psr |= PSR_OVF;
3475187d 256
3475187d 257 if (!T0)
0f8a249a 258 env->xcc |= PSR_ZERO;
3475187d 259 if ((int64_t) T0 < 0)
0f8a249a 260 env->xcc |= PSR_NEG;
3475187d 261 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
0f8a249a 262 env->xcc |= PSR_OVF;
3475187d 263#else
cf495bcf 264 if (!T0)
0f8a249a 265 env->psr |= PSR_ZERO;
af7bf89b 266 if ((int32_t) T0 < 0)
0f8a249a 267 env->psr |= PSR_NEG;
cf495bcf 268 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
0f8a249a 269 env->psr |= PSR_OVF;
3475187d 270#endif
cf495bcf 271 FORCE_RET();
7a3f1944
FB
272}
273
e32f879d
BS
274void OPPROTO op_tadd_T1_T0_cc(void)
275{
276 target_ulong src1;
277
278 src1 = T0;
279 T0 += T1;
280 env->psr = 0;
281#ifdef TARGET_SPARC64
282 if (!(T0 & 0xffffffff))
0f8a249a 283 env->psr |= PSR_ZERO;
e32f879d 284 if ((int32_t) T0 < 0)
0f8a249a 285 env->psr |= PSR_NEG;
e32f879d 286 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
0f8a249a 287 env->psr |= PSR_CARRY;
e32f879d 288 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
0f8a249a
BS
289 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
290 env->psr |= PSR_OVF;
e32f879d 291 if ((src1 & 0x03) || (T1 & 0x03))
0f8a249a 292 env->psr |= PSR_OVF;
e32f879d
BS
293
294 env->xcc = 0;
295 if (!T0)
0f8a249a 296 env->xcc |= PSR_ZERO;
e32f879d 297 if ((int64_t) T0 < 0)
0f8a249a 298 env->xcc |= PSR_NEG;
e32f879d 299 if (T0 < src1)
0f8a249a 300 env->xcc |= PSR_CARRY;
e32f879d 301 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
0f8a249a 302 env->xcc |= PSR_OVF;
e32f879d
BS
303#else
304 if (!T0)
0f8a249a 305 env->psr |= PSR_ZERO;
e32f879d 306 if ((int32_t) T0 < 0)
0f8a249a 307 env->psr |= PSR_NEG;
e32f879d 308 if (T0 < src1)
0f8a249a 309 env->psr |= PSR_CARRY;
e32f879d 310 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
0f8a249a 311 env->psr |= PSR_OVF;
e32f879d 312 if ((src1 & 0x03) || (T1 & 0x03))
0f8a249a 313 env->psr |= PSR_OVF;
e32f879d
BS
314#endif
315 FORCE_RET();
316}
317
318void OPPROTO op_tadd_T1_T0_ccTV(void)
319{
320 target_ulong src1;
321
d69d2ca9 322 if ((T0 & 0x03) || (T1 & 0x03)) {
e32f879d 323 raise_exception(TT_TOVF);
d69d2ca9
BS
324 FORCE_RET();
325 return;
326 }
e32f879d
BS
327
328 src1 = T0;
329 T0 += T1;
330
331#ifdef TARGET_SPARC64
332 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
0f8a249a 333 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
e32f879d
BS
334 raise_exception(TT_TOVF);
335#else
90251fb9 336 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
e32f879d
BS
337 raise_exception(TT_TOVF);
338#endif
339
340 env->psr = 0;
341#ifdef TARGET_SPARC64
342 if (!(T0 & 0xffffffff))
0f8a249a 343 env->psr |= PSR_ZERO;
e32f879d 344 if ((int32_t) T0 < 0)
0f8a249a 345 env->psr |= PSR_NEG;
e32f879d 346 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
0f8a249a 347 env->psr |= PSR_CARRY;
e32f879d
BS
348
349 env->xcc = 0;
350 if (!T0)
0f8a249a 351 env->xcc |= PSR_ZERO;
e32f879d 352 if ((int64_t) T0 < 0)
0f8a249a 353 env->xcc |= PSR_NEG;
e32f879d 354 if (T0 < src1)
0f8a249a 355 env->xcc |= PSR_CARRY;
e32f879d
BS
356#else
357 if (!T0)
0f8a249a 358 env->psr |= PSR_ZERO;
e32f879d 359 if ((int32_t) T0 < 0)
0f8a249a 360 env->psr |= PSR_NEG;
e32f879d 361 if (T0 < src1)
0f8a249a 362 env->psr |= PSR_CARRY;
e32f879d
BS
363#endif
364 FORCE_RET();
365}
366
cf495bcf 367void OPPROTO op_sub_T1_T0_cc(void)
7a3f1944 368{
af7bf89b 369 target_ulong src1;
cf495bcf
FB
370
371 src1 = T0;
372 T0 -= T1;
373 env->psr = 0;
3475187d
FB
374#ifdef TARGET_SPARC64
375 if (!(T0 & 0xffffffff))
0f8a249a 376 env->psr |= PSR_ZERO;
3475187d 377 if ((int32_t) T0 < 0)
0f8a249a 378 env->psr |= PSR_NEG;
83469015 379 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
0f8a249a 380 env->psr |= PSR_CARRY;
3475187d 381 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
0f8a249a
BS
382 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
383 env->psr |= PSR_OVF;
3475187d
FB
384
385 env->xcc = 0;
386 if (!T0)
0f8a249a 387 env->xcc |= PSR_ZERO;
3475187d 388 if ((int64_t) T0 < 0)
0f8a249a 389 env->xcc |= PSR_NEG;
bb3911a6 390 if (src1 < T1)
0f8a249a 391 env->xcc |= PSR_CARRY;
3475187d 392 if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
0f8a249a 393 env->xcc |= PSR_OVF;
3475187d 394#else
cf495bcf 395 if (!T0)
0f8a249a 396 env->psr |= PSR_ZERO;
af7bf89b 397 if ((int32_t) T0 < 0)
0f8a249a 398 env->psr |= PSR_NEG;
cf495bcf 399 if (src1 < T1)
0f8a249a 400 env->psr |= PSR_CARRY;
cf495bcf 401 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
0f8a249a 402 env->psr |= PSR_OVF;
3475187d 403#endif
af7bf89b
FB
404 FORCE_RET();
405}
406
af7bf89b
FB
407void OPPROTO op_subx_T1_T0_cc(void)
408{
409 target_ulong src1;
af7bf89b 410 src1 = T0;
b854608e
FB
411 if (FLAG_SET(PSR_CARRY))
412 {
413 T0 -= T1 + 1;
414 env->psr = 0;
415#ifdef TARGET_SPARC64
416 if ((src1 & 0xffffffff) <= (T1 & 0xffffffff))
417 env->psr |= PSR_CARRY;
418 env->xcc = 0;
419 if (src1 <= T1)
420 env->xcc |= PSR_CARRY;
421#else
422 if (src1 <= T1)
423 env->psr |= PSR_CARRY;
424#endif
425 }
426 else
427 {
428 T0 -= T1;
429 env->psr = 0;
430#ifdef TARGET_SPARC64
431 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
432 env->psr |= PSR_CARRY;
433 env->xcc = 0;
434 if (src1 < T1)
435 env->xcc |= PSR_CARRY;
436#else
437 if (src1 < T1)
438 env->psr |= PSR_CARRY;
439#endif
440 }
3475187d
FB
441#ifdef TARGET_SPARC64
442 if (!(T0 & 0xffffffff))
0f8a249a 443 env->psr |= PSR_ZERO;
3475187d 444 if ((int32_t) T0 < 0)
0f8a249a 445 env->psr |= PSR_NEG;
3475187d 446 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
0f8a249a
BS
447 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
448 env->psr |= PSR_OVF;
3475187d 449
3475187d 450 if (!T0)
0f8a249a 451 env->xcc |= PSR_ZERO;
3475187d 452 if ((int64_t) T0 < 0)
0f8a249a 453 env->xcc |= PSR_NEG;
3475187d 454 if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
0f8a249a 455 env->xcc |= PSR_OVF;
3475187d 456#else
af7bf89b 457 if (!T0)
0f8a249a 458 env->psr |= PSR_ZERO;
af7bf89b 459 if ((int32_t) T0 < 0)
0f8a249a 460 env->psr |= PSR_NEG;
af7bf89b 461 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
0f8a249a 462 env->psr |= PSR_OVF;
3475187d 463#endif
cf495bcf 464 FORCE_RET();
7a3f1944
FB
465}
466
e32f879d
BS
467void OPPROTO op_tsub_T1_T0_cc(void)
468{
469 target_ulong src1;
470
471 src1 = T0;
472 T0 -= T1;
473 env->psr = 0;
474#ifdef TARGET_SPARC64
475 if (!(T0 & 0xffffffff))
0f8a249a 476 env->psr |= PSR_ZERO;
e32f879d 477 if ((int32_t) T0 < 0)
0f8a249a 478 env->psr |= PSR_NEG;
e32f879d 479 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
0f8a249a 480 env->psr |= PSR_CARRY;
e32f879d 481 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
0f8a249a
BS
482 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
483 env->psr |= PSR_OVF;
e32f879d 484 if ((src1 & 0x03) || (T1 & 0x03))
0f8a249a 485 env->psr |= PSR_OVF;
e32f879d
BS
486
487 env->xcc = 0;
488 if (!T0)
0f8a249a 489 env->xcc |= PSR_ZERO;
e32f879d 490 if ((int64_t) T0 < 0)
0f8a249a 491 env->xcc |= PSR_NEG;
e32f879d 492 if (src1 < T1)
0f8a249a 493 env->xcc |= PSR_CARRY;
e32f879d 494 if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
0f8a249a 495 env->xcc |= PSR_OVF;
e32f879d
BS
496#else
497 if (!T0)
0f8a249a 498 env->psr |= PSR_ZERO;
e32f879d 499 if ((int32_t) T0 < 0)
0f8a249a 500 env->psr |= PSR_NEG;
e32f879d 501 if (src1 < T1)
0f8a249a 502 env->psr |= PSR_CARRY;
e32f879d 503 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
0f8a249a 504 env->psr |= PSR_OVF;
e32f879d 505 if ((src1 & 0x03) || (T1 & 0x03))
0f8a249a 506 env->psr |= PSR_OVF;
e32f879d
BS
507#endif
508 FORCE_RET();
509}
510
511void OPPROTO op_tsub_T1_T0_ccTV(void)
512{
513 target_ulong src1;
514
515 if ((T0 & 0x03) || (T1 & 0x03))
516 raise_exception(TT_TOVF);
517
518 src1 = T0;
519 T0 -= T1;
520
521#ifdef TARGET_SPARC64
522 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
0f8a249a 523 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
e32f879d
BS
524 raise_exception(TT_TOVF);
525#else
526 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
527 raise_exception(TT_TOVF);
528#endif
529
530 env->psr = 0;
531#ifdef TARGET_SPARC64
532 if (!(T0 & 0xffffffff))
0f8a249a 533 env->psr |= PSR_ZERO;
e32f879d 534 if ((int32_t) T0 < 0)
0f8a249a 535 env->psr |= PSR_NEG;
e32f879d 536 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
0f8a249a 537 env->psr |= PSR_CARRY;
e32f879d
BS
538
539 env->xcc = 0;
540 if (!T0)
0f8a249a 541 env->xcc |= PSR_ZERO;
e32f879d 542 if ((int64_t) T0 < 0)
0f8a249a 543 env->xcc |= PSR_NEG;
e32f879d 544 if (src1 < T1)
0f8a249a 545 env->xcc |= PSR_CARRY;
e32f879d
BS
546#else
547 if (!T0)
0f8a249a 548 env->psr |= PSR_ZERO;
e32f879d 549 if ((int32_t) T0 < 0)
0f8a249a 550 env->psr |= PSR_NEG;
e32f879d 551 if (src1 < T1)
0f8a249a 552 env->psr |= PSR_CARRY;
e32f879d
BS
553#endif
554 FORCE_RET();
555}
556
cf495bcf 557void OPPROTO op_umul_T1_T0(void)
7a3f1944 558{
cf495bcf 559 uint64_t res;
af7bf89b 560 res = (uint64_t) T0 * (uint64_t) T1;
83469015
FB
561#ifdef TARGET_SPARC64
562 T0 = res;
563#else
cf495bcf 564 T0 = res & 0xffffffff;
83469015 565#endif
cf495bcf 566 env->y = res >> 32;
7a3f1944
FB
567}
568
cf495bcf 569void OPPROTO op_smul_T1_T0(void)
7a3f1944 570{
cf495bcf
FB
571 uint64_t res;
572 res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
83469015
FB
573#ifdef TARGET_SPARC64
574 T0 = res;
575#else
cf495bcf 576 T0 = res & 0xffffffff;
83469015 577#endif
cf495bcf 578 env->y = res >> 32;
7a3f1944
FB
579}
580
cf495bcf 581void OPPROTO op_mulscc_T1_T0(void)
7a3f1944 582{
af7bf89b
FB
583 unsigned int b1, N, V, b2;
584 target_ulong src1;
585
4e8b5da2 586 N = FLAG_SET(PSR_NEG);
cf495bcf 587 V = FLAG_SET(PSR_OVF);
4e8b5da2 588 b1 = N ^ V;
cf495bcf
FB
589 b2 = T0 & 1;
590 T0 = (b1 << 31) | (T0 >> 1);
591 if (!(env->y & 1))
592 T1 = 0;
593 /* do addition and update flags */
594 src1 = T0;
595 T0 += T1;
596 env->psr = 0;
597 if (!T0)
0f8a249a 598 env->psr |= PSR_ZERO;
af7bf89b 599 if ((int32_t) T0 < 0)
0f8a249a 600 env->psr |= PSR_NEG;
cf495bcf 601 if (T0 < src1)
0f8a249a 602 env->psr |= PSR_CARRY;
cf495bcf 603 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
0f8a249a 604 env->psr |= PSR_OVF;
cf495bcf
FB
605 env->y = (b2 << 31) | (env->y >> 1);
606 FORCE_RET();
607}
608
609void OPPROTO op_udiv_T1_T0(void)
610{
611 uint64_t x0;
612 uint32_t x1;
613
614 x0 = T0 | ((uint64_t) (env->y) << 32);
615 x1 = T1;
9bb234b3
TS
616
617 if (x1 == 0) {
618 raise_exception(TT_DIV_ZERO);
619 }
620
cf495bcf
FB
621 x0 = x0 / x1;
622 if (x0 > 0xffffffff) {
0f8a249a
BS
623 T0 = 0xffffffff;
624 T1 = 1;
cf495bcf 625 } else {
0f8a249a
BS
626 T0 = x0;
627 T1 = 0;
cf495bcf
FB
628 }
629 FORCE_RET();
7a3f1944
FB
630}
631
cf495bcf 632void OPPROTO op_sdiv_T1_T0(void)
7a3f1944 633{
cf495bcf
FB
634 int64_t x0;
635 int32_t x1;
636
af7bf89b 637 x0 = T0 | ((int64_t) (env->y) << 32);
cf495bcf 638 x1 = T1;
9bb234b3
TS
639
640 if (x1 == 0) {
641 raise_exception(TT_DIV_ZERO);
642 }
643
cf495bcf
FB
644 x0 = x0 / x1;
645 if ((int32_t) x0 != x0) {
0f8a249a
BS
646 T0 = x0 < 0? 0x80000000: 0x7fffffff;
647 T1 = 1;
cf495bcf 648 } else {
0f8a249a
BS
649 T0 = x0;
650 T1 = 0;
cf495bcf
FB
651 }
652 FORCE_RET();
7a3f1944
FB
653}
654
cf495bcf 655void OPPROTO op_div_cc(void)
7a3f1944 656{
cf495bcf 657 env->psr = 0;
3475187d
FB
658#ifdef TARGET_SPARC64
659 if (!T0)
0f8a249a 660 env->psr |= PSR_ZERO;
3475187d 661 if ((int32_t) T0 < 0)
0f8a249a 662 env->psr |= PSR_NEG;
3475187d 663 if (T1)
0f8a249a 664 env->psr |= PSR_OVF;
3475187d
FB
665
666 env->xcc = 0;
667 if (!T0)
0f8a249a 668 env->xcc |= PSR_ZERO;
3475187d 669 if ((int64_t) T0 < 0)
0f8a249a 670 env->xcc |= PSR_NEG;
3475187d 671#else
cf495bcf 672 if (!T0)
0f8a249a 673 env->psr |= PSR_ZERO;
af7bf89b 674 if ((int32_t) T0 < 0)
0f8a249a 675 env->psr |= PSR_NEG;
cf495bcf 676 if (T1)
0f8a249a 677 env->psr |= PSR_OVF;
3475187d 678#endif
cf495bcf 679 FORCE_RET();
7a3f1944
FB
680}
681
3475187d 682#ifdef TARGET_SPARC64
3475187d
FB
683void OPPROTO op_udivx_T1_T0(void)
684{
14a1120e
BS
685 if (T1 == 0) {
686 raise_exception(TT_DIV_ZERO);
687 }
3475187d
FB
688 T0 /= T1;
689 FORCE_RET();
690}
691
692void OPPROTO op_sdivx_T1_T0(void)
693{
14a1120e
BS
694 if (T1 == 0) {
695 raise_exception(TT_DIV_ZERO);
696 }
3475187d 697 if (T0 == INT64_MIN && T1 == -1)
0f8a249a 698 T0 = INT64_MIN;
3475187d 699 else
0f8a249a 700 T0 /= (target_long) T1;
3475187d
FB
701 FORCE_RET();
702}
703#endif
704
cf495bcf 705void OPPROTO op_logic_T0_cc(void)
7a3f1944 706{
cf495bcf 707 env->psr = 0;
3475187d
FB
708#ifdef TARGET_SPARC64
709 if (!(T0 & 0xffffffff))
0f8a249a 710 env->psr |= PSR_ZERO;
3475187d 711 if ((int32_t) T0 < 0)
0f8a249a 712 env->psr |= PSR_NEG;
3475187d
FB
713
714 env->xcc = 0;
715 if (!T0)
0f8a249a 716 env->xcc |= PSR_ZERO;
3475187d 717 if ((int64_t) T0 < 0)
0f8a249a 718 env->xcc |= PSR_NEG;
3475187d 719#else
cf495bcf 720 if (!T0)
0f8a249a 721 env->psr |= PSR_ZERO;
af7bf89b 722 if ((int32_t) T0 < 0)
0f8a249a 723 env->psr |= PSR_NEG;
3475187d 724#endif
cf495bcf 725 FORCE_RET();
7a3f1944
FB
726}
727
e8af50a3
FB
728/* Load and store */
729#define MEMSUFFIX _raw
730#include "op_mem.h"
731#if !defined(CONFIG_USER_ONLY)
732#define MEMSUFFIX _user
733#include "op_mem.h"
734
735#define MEMSUFFIX _kernel
736#include "op_mem.h"
6f27aba6
BS
737
738#ifdef TARGET_SPARC64
739#define MEMSUFFIX _hypv
740#include "op_mem.h"
741#endif
e8af50a3 742#endif
e8af50a3
FB
743
744void OPPROTO op_ldfsr(void)
745{
3475187d 746 PUT_FSR32(env, *((uint32_t *) &FT0));
e8af50a3
FB
747}
748
749void OPPROTO op_stfsr(void)
750{
3475187d 751 *((uint32_t *) &FT0) = GET_FSR32(env);
e8af50a3
FB
752}
753
3475187d 754#ifndef TARGET_SPARC64
3475187d
FB
755/* XXX: use another pointer for %iN registers to avoid slow wrapping
756 handling ? */
757void OPPROTO op_save(void)
e8af50a3 758{
3475187d 759 uint32_t cwp;
5fafdf24 760 cwp = (env->cwp - 1) & (NWINDOWS - 1);
3475187d
FB
761 if (env->wim & (1 << cwp)) {
762 raise_exception(TT_WIN_OVF);
763 }
764 set_cwp(cwp);
e8af50a3
FB
765 FORCE_RET();
766}
767
3475187d 768void OPPROTO op_restore(void)
e8af50a3 769{
3475187d 770 uint32_t cwp;
5fafdf24 771 cwp = (env->cwp + 1) & (NWINDOWS - 1);
3475187d
FB
772 if (env->wim & (1 << cwp)) {
773 raise_exception(TT_WIN_UNF);
774 }
775 set_cwp(cwp);
776 FORCE_RET();
777}
778#else
779void OPPROTO op_rdccr(void)
780{
781 T0 = GET_CCR(env);
e8af50a3
FB
782}
783
3475187d 784void OPPROTO op_wrccr(void)
e8af50a3 785{
3475187d 786 PUT_CCR(env, T0);
e8af50a3
FB
787}
788
3475187d
FB
789// CWP handling is reversed in V9, but we still use the V8 register
790// order.
791void OPPROTO op_rdcwp(void)
792{
17d996e1 793 T0 = GET_CWP64(env);
3475187d
FB
794}
795
796void OPPROTO op_wrcwp(void)
797{
17d996e1 798 PUT_CWP64(env, T0);
cf495bcf 799}
7a3f1944 800
cf495bcf
FB
801/* XXX: use another pointer for %iN registers to avoid slow wrapping
802 handling ? */
803void OPPROTO op_save(void)
7a3f1944 804{
af7bf89b 805 uint32_t cwp;
5fafdf24 806 cwp = (env->cwp - 1) & (NWINDOWS - 1);
3475187d 807 if (env->cansave == 0) {
5fafdf24 808 raise_exception(TT_SPILL | (env->otherwin != 0 ?
0f8a249a
BS
809 (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
810 ((env->wstate & 0x7) << 2)));
3475187d 811 } else {
0f8a249a
BS
812 if (env->cleanwin - env->canrestore == 0) {
813 // XXX Clean windows without trap
814 raise_exception(TT_CLRWIN);
815 } else {
816 env->cansave--;
817 env->canrestore++;
818 set_cwp(cwp);
819 }
cf495bcf 820 }
cf495bcf 821 FORCE_RET();
7a3f1944
FB
822}
823
cf495bcf 824void OPPROTO op_restore(void)
7a3f1944 825{
af7bf89b 826 uint32_t cwp;
5fafdf24 827 cwp = (env->cwp + 1) & (NWINDOWS - 1);
3475187d 828 if (env->canrestore == 0) {
5fafdf24 829 raise_exception(TT_FILL | (env->otherwin != 0 ?
0f8a249a
BS
830 (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
831 ((env->wstate & 0x7) << 2)));
3475187d 832 } else {
0f8a249a
BS
833 env->cansave++;
834 env->canrestore--;
835 set_cwp(cwp);
cf495bcf 836 }
cf495bcf 837 FORCE_RET();
7a3f1944 838}
3475187d 839#endif
7a3f1944 840
83469015 841void OPPROTO op_jmp_label(void)
72cbca10 842{
83469015
FB
843 GOTO_LABEL_PARAM(1);
844}
845
65ce8c2f
FB
846#define F_OP(name, p) void OPPROTO op_f##name##p(void)
847
1f587329 848#if defined(CONFIG_USER_ONLY)
65ce8c2f
FB
849#define F_BINOP(name) \
850 F_OP(name, s) \
851 { \
852 FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
853 } \
854 F_OP(name, d) \
855 { \
856 DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
1f587329
BS
857 } \
858 F_OP(name, q) \
859 { \
1f587329 860 QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \
65ce8c2f 861 }
1f587329
BS
862#else
863#define F_BINOP(name) \
864 F_OP(name, s) \
865 { \
1f587329 866 FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
1f587329
BS
867 } \
868 F_OP(name, d) \
869 { \
1f587329 870 DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
1f587329
BS
871 }
872#endif
e8af50a3 873
65ce8c2f
FB
874F_BINOP(add);
875F_BINOP(sub);
876F_BINOP(mul);
877F_BINOP(div);
878#undef F_BINOP
e8af50a3
FB
879
880void OPPROTO op_fsmuld(void)
881{
65ce8c2f
FB
882 DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status),
883 float32_to_float64(FT1, &env->fp_status),
884 &env->fp_status);
e8af50a3
FB
885}
886
1f587329
BS
887#if defined(CONFIG_USER_ONLY)
888void OPPROTO op_fdmulq(void)
889{
1f587329
BS
890 QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status),
891 float64_to_float128(DT1, &env->fp_status),
892 &env->fp_status);
1f587329
BS
893}
894#endif
895
896#if defined(CONFIG_USER_ONLY)
65ce8c2f
FB
897#define F_HELPER(name) \
898 F_OP(name, s) \
899 { \
900 do_f##name##s(); \
901 } \
902 F_OP(name, d) \
903 { \
904 do_f##name##d(); \
1f587329
BS
905 } \
906 F_OP(name, q) \
907 { \
908 do_f##name##q(); \
65ce8c2f 909 }
1f587329
BS
910#else
911#define F_HELPER(name) \
912 F_OP(name, s) \
913 { \
914 do_f##name##s(); \
915 } \
916 F_OP(name, d) \
917 { \
918 do_f##name##d(); \
919 }
920#endif
e8af50a3 921
65ce8c2f 922F_OP(neg, s)
e8af50a3 923{
65ce8c2f 924 FT0 = float32_chs(FT1);
e8af50a3
FB
925}
926
65ce8c2f
FB
927#ifdef TARGET_SPARC64
928F_OP(neg, d)
e8af50a3 929{
65ce8c2f 930 DT0 = float64_chs(DT1);
e8af50a3
FB
931}
932
1f587329
BS
933#if defined(CONFIG_USER_ONLY)
934F_OP(neg, q)
935{
936 QT0 = float128_chs(QT1);
937}
938
1f587329
BS
939#endif
940
3475187d
FB
941#endif
942
65ce8c2f 943/* Integer to float conversion. */
a0c4cb4a 944#ifdef USE_INT_TO_FLOAT_HELPERS
65ce8c2f 945F_HELPER(ito);
1e64e78d
BS
946#ifdef TARGET_SPARC64
947F_HELPER(xto);
948#endif
a0c4cb4a 949#else
65ce8c2f 950F_OP(ito, s)
a0c4cb4a 951{
65ce8c2f 952 FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
e8af50a3
FB
953}
954
65ce8c2f 955F_OP(ito, d)
e8af50a3 956{
65ce8c2f 957 DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
e8af50a3 958}
3475187d 959
1f587329
BS
960#if defined(CONFIG_USER_ONLY)
961F_OP(ito, q)
962{
1f587329 963 QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
1f587329
BS
964}
965#endif
966
3475187d 967#ifdef TARGET_SPARC64
65ce8c2f 968F_OP(xto, s)
3475187d 969{
65ce8c2f 970 FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
3475187d
FB
971}
972
65ce8c2f 973F_OP(xto, d)
3475187d 974{
65ce8c2f 975 DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
3475187d 976}
1f587329
BS
977#if defined(CONFIG_USER_ONLY)
978F_OP(xto, q)
979{
1f587329 980 QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
1f587329
BS
981}
982#endif
3475187d 983#endif
a0c4cb4a 984#endif
65ce8c2f 985#undef F_HELPER
a0c4cb4a 986
65ce8c2f 987/* floating point conversion */
a0c4cb4a
FB
988void OPPROTO op_fdtos(void)
989{
65ce8c2f 990 FT0 = float64_to_float32(DT1, &env->fp_status);
a0c4cb4a 991}
e8af50a3
FB
992
993void OPPROTO op_fstod(void)
994{
65ce8c2f 995 DT0 = float32_to_float64(FT1, &env->fp_status);
e8af50a3
FB
996}
997
1f587329
BS
998#if defined(CONFIG_USER_ONLY)
999void OPPROTO op_fqtos(void)
1000{
1f587329 1001 FT0 = float128_to_float32(QT1, &env->fp_status);
1f587329
BS
1002}
1003
1004void OPPROTO op_fstoq(void)
1005{
1f587329 1006 QT0 = float32_to_float128(FT1, &env->fp_status);
1f587329
BS
1007}
1008
1009void OPPROTO op_fqtod(void)
1010{
1f587329 1011 DT0 = float128_to_float64(QT1, &env->fp_status);
1f587329
BS
1012}
1013
1014void OPPROTO op_fdtoq(void)
1015{
1f587329 1016 QT0 = float64_to_float128(DT1, &env->fp_status);
1f587329
BS
1017}
1018#endif
1019
65ce8c2f 1020/* Float to integer conversion. */
e8af50a3
FB
1021void OPPROTO op_fstoi(void)
1022{
bd59780c 1023 *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status);
e8af50a3
FB
1024}
1025
1026void OPPROTO op_fdtoi(void)
1027{
bd59780c 1028 *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
e8af50a3
FB
1029}
1030
1f587329
BS
1031#if defined(CONFIG_USER_ONLY)
1032void OPPROTO op_fqtoi(void)
1033{
1f587329 1034 *((int32_t *)&FT0) = float128_to_int32_round_to_zero(QT1, &env->fp_status);
1f587329
BS
1035}
1036#endif
1037
3475187d
FB
1038#ifdef TARGET_SPARC64
1039void OPPROTO op_fstox(void)
1040{
bd59780c 1041 *((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status);
3475187d
FB
1042}
1043
1044void OPPROTO op_fdtox(void)
1045{
bd59780c 1046 *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
3475187d
FB
1047}
1048
1f587329
BS
1049#if defined(CONFIG_USER_ONLY)
1050void OPPROTO op_fqtox(void)
1051{
1f587329 1052 *((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status);
1f587329
BS
1053}
1054#endif
1055
3475187d
FB
1056void OPPROTO op_flushw(void)
1057{
1058 if (env->cansave != NWINDOWS - 2) {
5fafdf24 1059 raise_exception(TT_SPILL | (env->otherwin != 0 ?
0f8a249a
BS
1060 (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1061 ((env->wstate & 0x7) << 2)));
3475187d
FB
1062 }
1063}
1064
1065void OPPROTO op_saved(void)
1066{
1067 env->cansave++;
1068 if (env->otherwin == 0)
0f8a249a 1069 env->canrestore--;
725cb90b 1070 else
0f8a249a 1071 env->otherwin--;
725cb90b 1072 FORCE_RET();
3475187d
FB
1073}
1074
1075void OPPROTO op_restored(void)
1076{
1077 env->canrestore++;
1078 if (env->cleanwin < NWINDOWS - 1)
0f8a249a 1079 env->cleanwin++;
3475187d 1080 if (env->otherwin == 0)
0f8a249a 1081 env->cansave--;
3475187d 1082 else
0f8a249a 1083 env->otherwin--;
725cb90b 1084 FORCE_RET();
3475187d 1085}
81ad8ba2
BS
1086#endif
1087
725cb90b 1088#ifdef TARGET_SPARC64
e9ebed4d
BS
1089// This function uses non-native bit order
1090#define GET_FIELD(X, FROM, TO) \
1091 ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
1092
1093// This function uses the order in the manuals, i.e. bit 0 is 2^0
1094#define GET_FIELD_SP(X, FROM, TO) \
1095 GET_FIELD(X, 63 - (TO), 63 - (FROM))
1096
1097void OPPROTO op_array8()
1098{
1099 T0 = (GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1100 (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1101 (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1102 (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1103 (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1104 (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12);
1105}
1106
1107void OPPROTO op_array16()
1108{
1109 T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1110 (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1111 (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1112 (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1113 (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1114 (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 1;
1115}
1116
1117void OPPROTO op_array32()
1118{
1119 T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1120 (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1121 (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1122 (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1123 (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1124 (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 2;
1125}
1126
725cb90b
FB
1127void OPPROTO op_alignaddr()
1128{
1129 uint64_t tmp;
1130
1131 tmp = T0 + T1;
1132 env->gsr &= ~7ULL;
1133 env->gsr |= tmp & 7ULL;
1134 T0 = tmp & ~7ULL;
1135}
1136
1137void OPPROTO op_faligndata()
1138{
1139 uint64_t tmp;
1140
1141 tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8);
1142 tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
e9ebed4d 1143 *((uint64_t *)&DT0) = tmp;
725cb90b 1144}
3299908c
BS
1145
1146void OPPROTO op_movl_FT0_0(void)
1147{
e9ebed4d 1148 *((uint32_t *)&FT0) = 0;
3299908c
BS
1149}
1150
1151void OPPROTO op_movl_DT0_0(void)
1152{
e9ebed4d 1153 *((uint64_t *)&DT0) = 0;
3299908c
BS
1154}
1155
1156void OPPROTO op_movl_FT0_1(void)
1157{
e9ebed4d 1158 *((uint32_t *)&FT0) = 0xffffffff;
3299908c
BS
1159}
1160
1161void OPPROTO op_movl_DT0_1(void)
1162{
e9ebed4d
BS
1163 *((uint64_t *)&DT0) = 0xffffffffffffffffULL;
1164}
1165
1166void OPPROTO op_fnot(void)
1167{
1168 *(uint64_t *)&DT0 = ~*(uint64_t *)&DT1;
1169}
1170
1171void OPPROTO op_fnots(void)
1172{
1173 *(uint32_t *)&FT0 = ~*(uint32_t *)&FT1;
1174}
1175
1176void OPPROTO op_fnor(void)
1177{
1178 *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 | *(uint64_t *)&DT1);
1179}
1180
1181void OPPROTO op_fnors(void)
1182{
1183 *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 | *(uint32_t *)&FT1);
1184}
1185
1186void OPPROTO op_for(void)
1187{
1188 *(uint64_t *)&DT0 |= *(uint64_t *)&DT1;
1189}
1190
1191void OPPROTO op_fors(void)
1192{
1193 *(uint32_t *)&FT0 |= *(uint32_t *)&FT1;
1194}
1195
1196void OPPROTO op_fxor(void)
1197{
1198 *(uint64_t *)&DT0 ^= *(uint64_t *)&DT1;
1199}
1200
1201void OPPROTO op_fxors(void)
1202{
1203 *(uint32_t *)&FT0 ^= *(uint32_t *)&FT1;
1204}
1205
1206void OPPROTO op_fand(void)
1207{
1208 *(uint64_t *)&DT0 &= *(uint64_t *)&DT1;
1209}
1210
1211void OPPROTO op_fands(void)
1212{
1213 *(uint32_t *)&FT0 &= *(uint32_t *)&FT1;
1214}
1215
1216void OPPROTO op_fornot(void)
1217{
1218 *(uint64_t *)&DT0 = *(uint64_t *)&DT0 | ~*(uint64_t *)&DT1;
1219}
1220
1221void OPPROTO op_fornots(void)
1222{
1223 *(uint32_t *)&FT0 = *(uint32_t *)&FT0 | ~*(uint32_t *)&FT1;
1224}
1225
1226void OPPROTO op_fandnot(void)
1227{
1228 *(uint64_t *)&DT0 = *(uint64_t *)&DT0 & ~*(uint64_t *)&DT1;
1229}
1230
1231void OPPROTO op_fandnots(void)
1232{
1233 *(uint32_t *)&FT0 = *(uint32_t *)&FT0 & ~*(uint32_t *)&FT1;
1234}
1235
1236void OPPROTO op_fnand(void)
1237{
1238 *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 & *(uint64_t *)&DT1);
1239}
1240
1241void OPPROTO op_fnands(void)
1242{
1243 *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 & *(uint32_t *)&FT1);
1244}
1245
1246void OPPROTO op_fxnor(void)
1247{
1248 *(uint64_t *)&DT0 ^= ~*(uint64_t *)&DT1;
1249}
1250
1251void OPPROTO op_fxnors(void)
1252{
1253 *(uint32_t *)&FT0 ^= ~*(uint32_t *)&FT1;
1254}
1255
1256#ifdef WORDS_BIGENDIAN
1257#define VIS_B64(n) b[7 - (n)]
1258#define VIS_W64(n) w[3 - (n)]
1259#define VIS_SW64(n) sw[3 - (n)]
1260#define VIS_L64(n) l[1 - (n)]
1261#define VIS_B32(n) b[3 - (n)]
1262#define VIS_W32(n) w[1 - (n)]
1263#else
1264#define VIS_B64(n) b[n]
1265#define VIS_W64(n) w[n]
1266#define VIS_SW64(n) sw[n]
1267#define VIS_L64(n) l[n]
1268#define VIS_B32(n) b[n]
1269#define VIS_W32(n) w[n]
1270#endif
1271
1272typedef union {
1273 uint8_t b[8];
1274 uint16_t w[4];
1275 int16_t sw[4];
1276 uint32_t l[2];
1277 float64 d;
1278} vis64;
1279
1280typedef union {
1281 uint8_t b[4];
1282 uint16_t w[2];
1283 uint32_t l;
1284 float32 f;
1285} vis32;
1286
1287void OPPROTO op_fpmerge(void)
1288{
1289 vis64 s, d;
1290
1291 s.d = DT0;
1292 d.d = DT1;
1293
1294 // Reverse calculation order to handle overlap
1295 d.VIS_B64(7) = s.VIS_B64(3);
1296 d.VIS_B64(6) = d.VIS_B64(3);
1297 d.VIS_B64(5) = s.VIS_B64(2);
1298 d.VIS_B64(4) = d.VIS_B64(2);
1299 d.VIS_B64(3) = s.VIS_B64(1);
1300 d.VIS_B64(2) = d.VIS_B64(1);
1301 d.VIS_B64(1) = s.VIS_B64(0);
1302 //d.VIS_B64(0) = d.VIS_B64(0);
1303
1304 DT0 = d.d;
1305}
1306
1307void OPPROTO op_fmul8x16(void)
1308{
1309 vis64 s, d;
1310 uint32_t tmp;
1311
1312 s.d = DT0;
1313 d.d = DT1;
1314
1315#define PMUL(r) \
1316 tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r); \
1317 if ((tmp & 0xff) > 0x7f) \
1318 tmp += 0x100; \
1319 d.VIS_W64(r) = tmp >> 8;
1320
1321 PMUL(0);
1322 PMUL(1);
1323 PMUL(2);
1324 PMUL(3);
1325#undef PMUL
1326
1327 DT0 = d.d;
1328}
1329
1330void OPPROTO op_fmul8x16al(void)
1331{
1332 vis64 s, d;
1333 uint32_t tmp;
1334
1335 s.d = DT0;
1336 d.d = DT1;
1337
1338#define PMUL(r) \
1339 tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r); \
1340 if ((tmp & 0xff) > 0x7f) \
1341 tmp += 0x100; \
1342 d.VIS_W64(r) = tmp >> 8;
1343
1344 PMUL(0);
1345 PMUL(1);
1346 PMUL(2);
1347 PMUL(3);
1348#undef PMUL
1349
1350 DT0 = d.d;
3299908c 1351}
e9ebed4d
BS
1352
1353void OPPROTO op_fmul8x16au(void)
1354{
1355 vis64 s, d;
1356 uint32_t tmp;
1357
1358 s.d = DT0;
1359 d.d = DT1;
1360
1361#define PMUL(r) \
1362 tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r); \
1363 if ((tmp & 0xff) > 0x7f) \
1364 tmp += 0x100; \
1365 d.VIS_W64(r) = tmp >> 8;
1366
1367 PMUL(0);
1368 PMUL(1);
1369 PMUL(2);
1370 PMUL(3);
1371#undef PMUL
1372
1373 DT0 = d.d;
1374}
1375
1376void OPPROTO op_fmul8sux16(void)
1377{
1378 vis64 s, d;
1379 uint32_t tmp;
1380
1381 s.d = DT0;
1382 d.d = DT1;
1383
1384#define PMUL(r) \
1385 tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
1386 if ((tmp & 0xff) > 0x7f) \
1387 tmp += 0x100; \
1388 d.VIS_W64(r) = tmp >> 8;
1389
1390 PMUL(0);
1391 PMUL(1);
1392 PMUL(2);
1393 PMUL(3);
1394#undef PMUL
1395
1396 DT0 = d.d;
1397}
1398
1399void OPPROTO op_fmul8ulx16(void)
1400{
1401 vis64 s, d;
1402 uint32_t tmp;
1403
1404 s.d = DT0;
1405 d.d = DT1;
1406
1407#define PMUL(r) \
1408 tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
1409 if ((tmp & 0xff) > 0x7f) \
1410 tmp += 0x100; \
1411 d.VIS_W64(r) = tmp >> 8;
1412
1413 PMUL(0);
1414 PMUL(1);
1415 PMUL(2);
1416 PMUL(3);
1417#undef PMUL
1418
1419 DT0 = d.d;
1420}
1421
1422void OPPROTO op_fmuld8sux16(void)
1423{
1424 vis64 s, d;
1425 uint32_t tmp;
1426
1427 s.d = DT0;
1428 d.d = DT1;
1429
1430#define PMUL(r) \
1431 tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
1432 if ((tmp & 0xff) > 0x7f) \
1433 tmp += 0x100; \
1434 d.VIS_L64(r) = tmp;
1435
1436 // Reverse calculation order to handle overlap
1437 PMUL(1);
1438 PMUL(0);
1439#undef PMUL
1440
1441 DT0 = d.d;
1442}
1443
1444void OPPROTO op_fmuld8ulx16(void)
1445{
1446 vis64 s, d;
1447 uint32_t tmp;
1448
1449 s.d = DT0;
1450 d.d = DT1;
1451
1452#define PMUL(r) \
1453 tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
1454 if ((tmp & 0xff) > 0x7f) \
1455 tmp += 0x100; \
1456 d.VIS_L64(r) = tmp;
1457
1458 // Reverse calculation order to handle overlap
1459 PMUL(1);
1460 PMUL(0);
1461#undef PMUL
1462
1463 DT0 = d.d;
1464}
1465
1466void OPPROTO op_fexpand(void)
1467{
1468 vis32 s;
1469 vis64 d;
1470
1471 s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff);
1472 d.d = DT1;
1473 d.VIS_L64(0) = s.VIS_W32(0) << 4;
1474 d.VIS_L64(1) = s.VIS_W32(1) << 4;
1475 d.VIS_L64(2) = s.VIS_W32(2) << 4;
1476 d.VIS_L64(3) = s.VIS_W32(3) << 4;
1477
1478 DT0 = d.d;
1479}
1480
1481#define VIS_OP(name, F) \
1482 void OPPROTO name##16(void) \
1483 { \
1484 vis64 s, d; \
1485 \
1486 s.d = DT0; \
1487 d.d = DT1; \
1488 \
1489 d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0)); \
1490 d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1)); \
1491 d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2)); \
1492 d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3)); \
1493 \
1494 DT0 = d.d; \
1495 } \
1496 \
1497 void OPPROTO name##16s(void) \
1498 { \
1499 vis32 s, d; \
1500 \
1501 s.f = FT0; \
1502 d.f = FT1; \
1503 \
1504 d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0)); \
1505 d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1)); \
1506 \
1507 FT0 = d.f; \
1508 } \
1509 \
1510 void OPPROTO name##32(void) \
1511 { \
1512 vis64 s, d; \
1513 \
1514 s.d = DT0; \
1515 d.d = DT1; \
1516 \
1517 d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0)); \
1518 d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1)); \
1519 \
1520 DT0 = d.d; \
1521 } \
1522 \
1523 void OPPROTO name##32s(void) \
1524 { \
1525 vis32 s, d; \
1526 \
1527 s.f = FT0; \
1528 d.f = FT1; \
1529 \
1530 d.l = F(d.l, s.l); \
1531 \
1532 FT0 = d.f; \
1533 }
1534
1535#define FADD(a, b) ((a) + (b))
1536#define FSUB(a, b) ((a) - (b))
1537VIS_OP(op_fpadd, FADD)
1538VIS_OP(op_fpsub, FSUB)
1539
1540#define VIS_CMPOP(name, F) \
1541 void OPPROTO name##16(void) \
1542 { \
1543 vis64 s, d; \
1544 \
1545 s.d = DT0; \
1546 d.d = DT1; \
1547 \
1548 d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0; \
1549 d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0; \
1550 d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0; \
1551 d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0; \
1552 \
1553 DT0 = d.d; \
1554 } \
1555 \
1556 void OPPROTO name##32(void) \
1557 { \
1558 vis64 s, d; \
1559 \
1560 s.d = DT0; \
1561 d.d = DT1; \
1562 \
1563 d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0; \
1564 d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0; \
1565 \
1566 DT0 = d.d; \
1567 }
1568
1569#define FCMPGT(a, b) ((a) > (b))
1570#define FCMPEQ(a, b) ((a) == (b))
1571#define FCMPLE(a, b) ((a) <= (b))
1572#define FCMPNE(a, b) ((a) != (b))
1573
1574VIS_CMPOP(op_fcmpgt, FCMPGT)
1575VIS_CMPOP(op_fcmpeq, FCMPEQ)
1576VIS_CMPOP(op_fcmple, FCMPLE)
1577VIS_CMPOP(op_fcmpne, FCMPNE)
1578
725cb90b 1579#endif
6ea4a6c8
BS
1580
1581#define CHECK_ALIGN_OP(align) \
1582 void OPPROTO op_check_align_T0_ ## align (void) \
1583 { \
1584 if (T0 & align) \
1585 raise_exception(TT_UNALIGNED); \
1586 FORCE_RET(); \
1587 }
1588
1589CHECK_ALIGN_OP(1)
1590CHECK_ALIGN_OP(3)
1591CHECK_ALIGN_OP(7)
This page took 0.382374 seconds and 4 git commands to generate.