Statistics
| Branch: | Revision:

root / target-sparc / op.c @ 1f587329

History | View | Annotate | Download (56.4 kB)

1
/*
2
   SPARC micro operations
3

4
   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
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

    
23
 /*XXX*/
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 (REGWPTR[16])
50
#include "op_template.h"
51
#define REGNAME i1
52
#define REG (REGWPTR[17])
53
#include "op_template.h"
54
#define REGNAME i2
55
#define REG (REGWPTR[18])
56
#include "op_template.h"
57
#define REGNAME i3
58
#define REG (REGWPTR[19])
59
#include "op_template.h"
60
#define REGNAME i4
61
#define REG (REGWPTR[20])
62
#include "op_template.h"
63
#define REGNAME i5
64
#define REG (REGWPTR[21])
65
#include "op_template.h"
66
#define REGNAME i6
67
#define REG (REGWPTR[22])
68
#include "op_template.h"
69
#define REGNAME i7
70
#define REG (REGWPTR[23])
71
#include "op_template.h"
72
#define REGNAME l0
73
#define REG (REGWPTR[8])
74
#include "op_template.h"
75
#define REGNAME l1
76
#define REG (REGWPTR[9])
77
#include "op_template.h"
78
#define REGNAME l2
79
#define REG (REGWPTR[10])
80
#include "op_template.h"
81
#define REGNAME l3
82
#define REG (REGWPTR[11])
83
#include "op_template.h"
84
#define REGNAME l4
85
#define REG (REGWPTR[12])
86
#include "op_template.h"
87
#define REGNAME l5
88
#define REG (REGWPTR[13])
89
#include "op_template.h"
90
#define REGNAME l6
91
#define REG (REGWPTR[14])
92
#include "op_template.h"
93
#define REGNAME l7
94
#define REG (REGWPTR[15])
95
#include "op_template.h"
96
#define REGNAME o0
97
#define REG (REGWPTR[0])
98
#include "op_template.h"
99
#define REGNAME o1
100
#define REG (REGWPTR[1])
101
#include "op_template.h"
102
#define REGNAME o2
103
#define REG (REGWPTR[2])
104
#include "op_template.h"
105
#define REGNAME o3
106
#define REG (REGWPTR[3])
107
#include "op_template.h"
108
#define REGNAME o4
109
#define REG (REGWPTR[4])
110
#include "op_template.h"
111
#define REGNAME o5
112
#define REG (REGWPTR[5])
113
#include "op_template.h"
114
#define REGNAME o6
115
#define REG (REGWPTR[6])
116
#include "op_template.h"
117
#define REGNAME o7
118
#define REG (REGWPTR[7])
119
#include "op_template.h"
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

    
218
#ifdef TARGET_SPARC64
219
#define REGNAME f32
220
#define REG (env->fpr[32])
221
#include "fop_template.h"
222
#define REGNAME f34
223
#define REG (env->fpr[34])
224
#include "fop_template.h"
225
#define REGNAME f36
226
#define REG (env->fpr[36])
227
#include "fop_template.h"
228
#define REGNAME f38
229
#define REG (env->fpr[38])
230
#include "fop_template.h"
231
#define REGNAME f40
232
#define REG (env->fpr[40])
233
#include "fop_template.h"
234
#define REGNAME f42
235
#define REG (env->fpr[42])
236
#include "fop_template.h"
237
#define REGNAME f44
238
#define REG (env->fpr[44])
239
#include "fop_template.h"
240
#define REGNAME f46
241
#define REG (env->fpr[46])
242
#include "fop_template.h"
243
#define REGNAME f48
244
#define REG (env->fpr[47])
245
#include "fop_template.h"
246
#define REGNAME f50
247
#define REG (env->fpr[50])
248
#include "fop_template.h"
249
#define REGNAME f52
250
#define REG (env->fpr[52])
251
#include "fop_template.h"
252
#define REGNAME f54
253
#define REG (env->fpr[54])
254
#include "fop_template.h"
255
#define REGNAME f56
256
#define REG (env->fpr[56])
257
#include "fop_template.h"
258
#define REGNAME f58
259
#define REG (env->fpr[58])
260
#include "fop_template.h"
261
#define REGNAME f60
262
#define REG (env->fpr[60])
263
#include "fop_template.h"
264
#define REGNAME f62
265
#define REG (env->fpr[62])
266
#include "fop_template.h"
267
#endif
268

    
269
#ifdef TARGET_SPARC64
270
#ifdef WORDS_BIGENDIAN
271
typedef union UREG64 {
272
    struct { uint16_t v3, v2, v1, v0; } w;
273
    struct { uint32_t v1, v0; } l;
274
    uint64_t q;
275
} UREG64;
276
#else
277
typedef union UREG64 {
278
    struct { uint16_t v0, v1, v2, v3; } w;
279
    struct { uint32_t v0, v1; } l;
280
    uint64_t q;
281
} UREG64;
282
#endif
283

    
284
#define PARAMQ1 \
285
({\
286
    UREG64 __p;\
287
    __p.l.v1 = PARAM1;\
288
    __p.l.v0 = PARAM2;\
289
    __p.q;\
290
})
291

    
292
void OPPROTO op_movq_T0_im64(void)
293
{
294
    T0 = PARAMQ1;
295
}
296

    
297
void OPPROTO op_movq_T1_im64(void)
298
{
299
    T1 = PARAMQ1;
300
}
301

    
302
#define XFLAG_SET(x) ((env->xcc&x)?1:0)
303

    
304
#else
305
#define EIP (env->pc)
306
#endif
307

    
308
#define FLAG_SET(x) ((env->psr&x)?1:0)
309

    
310
void OPPROTO op_movl_T0_0(void)
311
{
312
    T0 = 0;
313
}
314

    
315
void OPPROTO op_movl_T0_im(void)
316
{
317
    T0 = (uint32_t)PARAM1;
318
}
319

    
320
void OPPROTO op_movl_T1_im(void)
321
{
322
    T1 = (uint32_t)PARAM1;
323
}
324

    
325
void OPPROTO op_movl_T2_im(void)
326
{
327
    T2 = (uint32_t)PARAM1;
328
}
329

    
330
void OPPROTO op_movl_T0_sim(void)
331
{
332
    T0 = (int32_t)PARAM1;
333
}
334

    
335
void OPPROTO op_movl_T1_sim(void)
336
{
337
    T1 = (int32_t)PARAM1;
338
}
339

    
340
void OPPROTO op_movl_T2_sim(void)
341
{
342
    T2 = (int32_t)PARAM1;
343
}
344

    
345
void OPPROTO op_movl_T0_env(void)
346
{
347
    T0 = *(uint32_t *)((char *)env + PARAM1);
348
}
349

    
350
void OPPROTO op_movl_env_T0(void)
351
{
352
    *(uint32_t *)((char *)env + PARAM1) = T0;
353
}
354

    
355
void OPPROTO op_movtl_T0_env(void)
356
{
357
    T0 = *(target_ulong *)((char *)env + PARAM1);
358
}
359

    
360
void OPPROTO op_movtl_env_T0(void)
361
{
362
    *(target_ulong *)((char *)env + PARAM1) = T0;
363
}
364

    
365
void OPPROTO op_add_T1_T0(void)
366
{
367
    T0 += T1;
368
}
369

    
370
void OPPROTO op_add_T1_T0_cc(void)
371
{
372
    target_ulong src1;
373

    
374
    src1 = T0;
375
    T0 += T1;
376
    env->psr = 0;
377
#ifdef TARGET_SPARC64
378
    if (!(T0 & 0xffffffff))
379
        env->psr |= PSR_ZERO;
380
    if ((int32_t) T0 < 0)
381
        env->psr |= PSR_NEG;
382
    if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
383
        env->psr |= PSR_CARRY;
384
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
385
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
386
        env->psr |= PSR_OVF;
387

    
388
    env->xcc = 0;
389
    if (!T0)
390
        env->xcc |= PSR_ZERO;
391
    if ((int64_t) T0 < 0)
392
        env->xcc |= PSR_NEG;
393
    if (T0 < src1)
394
        env->xcc |= PSR_CARRY;
395
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
396
        env->xcc |= PSR_OVF;
397
#else
398
    if (!T0)
399
        env->psr |= PSR_ZERO;
400
    if ((int32_t) T0 < 0)
401
        env->psr |= PSR_NEG;
402
    if (T0 < src1)
403
        env->psr |= PSR_CARRY;
404
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
405
        env->psr |= PSR_OVF;
406
#endif
407
    FORCE_RET();
408
}
409

    
410
void OPPROTO op_addx_T1_T0(void)
411
{
412
    T0 += T1 + FLAG_SET(PSR_CARRY);
413
}
414

    
415
void OPPROTO op_addx_T1_T0_cc(void)
416
{
417
    target_ulong src1;
418
    src1 = T0;
419
    if (FLAG_SET(PSR_CARRY))
420
    {
421
      T0 += T1 + 1;
422
      env->psr = 0;
423
#ifdef TARGET_SPARC64
424
      if ((T0 & 0xffffffff) <= (src1 & 0xffffffff))
425
        env->psr |= PSR_CARRY;
426
      env->xcc = 0;
427
      if (T0 <= src1)
428
        env->xcc |= PSR_CARRY;
429
#else
430
      if (T0 <= src1)
431
        env->psr |= PSR_CARRY;
432
#endif
433
    }
434
    else
435
    {
436
      T0 += T1;
437
      env->psr = 0;
438
#ifdef TARGET_SPARC64
439
      if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
440
        env->psr |= PSR_CARRY;
441
      env->xcc = 0;
442
      if (T0 < src1)
443
        env->xcc |= PSR_CARRY;
444
#else
445
      if (T0 < src1)
446
        env->psr |= PSR_CARRY;
447
#endif
448
    }
449
#ifdef TARGET_SPARC64
450
    if (!(T0 & 0xffffffff))
451
        env->psr |= PSR_ZERO;
452
    if ((int32_t) T0 < 0)
453
        env->psr |= PSR_NEG;
454
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
455
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
456
        env->psr |= PSR_OVF;
457

    
458
    if (!T0)
459
        env->xcc |= PSR_ZERO;
460
    if ((int64_t) T0 < 0)
461
        env->xcc |= PSR_NEG;
462
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
463
        env->xcc |= PSR_OVF;
464
#else
465
    if (!T0)
466
        env->psr |= PSR_ZERO;
467
    if ((int32_t) T0 < 0)
468
        env->psr |= PSR_NEG;
469
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
470
        env->psr |= PSR_OVF;
471
#endif
472
    FORCE_RET();
473
}
474

    
475
void OPPROTO op_tadd_T1_T0_cc(void)
476
{
477
    target_ulong src1;
478

    
479
    src1 = T0;
480
    T0 += T1;
481
    env->psr = 0;
482
#ifdef TARGET_SPARC64
483
    if (!(T0 & 0xffffffff))
484
        env->psr |= PSR_ZERO;
485
    if ((int32_t) T0 < 0)
486
        env->psr |= PSR_NEG;
487
    if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
488
        env->psr |= PSR_CARRY;
489
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
490
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
491
        env->psr |= PSR_OVF;
492
    if ((src1 & 0x03) || (T1 & 0x03))
493
        env->psr |= PSR_OVF;
494

    
495
    env->xcc = 0;
496
    if (!T0)
497
        env->xcc |= PSR_ZERO;
498
    if ((int64_t) T0 < 0)
499
        env->xcc |= PSR_NEG;
500
    if (T0 < src1)
501
        env->xcc |= PSR_CARRY;
502
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
503
        env->xcc |= PSR_OVF;
504
#else
505
    if (!T0)
506
        env->psr |= PSR_ZERO;
507
    if ((int32_t) T0 < 0)
508
        env->psr |= PSR_NEG;
509
    if (T0 < src1)
510
        env->psr |= PSR_CARRY;
511
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
512
        env->psr |= PSR_OVF;
513
    if ((src1 & 0x03) || (T1 & 0x03))
514
        env->psr |= PSR_OVF;
515
#endif
516
    FORCE_RET();
517
}
518

    
519
void OPPROTO op_tadd_T1_T0_ccTV(void)
520
{
521
    target_ulong src1;
522

    
523
    if ((T0 & 0x03) || (T1 & 0x03)) {
524
        raise_exception(TT_TOVF);
525
        FORCE_RET();
526
        return;
527
    }
528

    
529
    src1 = T0;
530
    T0 += T1;
531

    
532
#ifdef TARGET_SPARC64
533
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
534
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
535
        raise_exception(TT_TOVF);
536
#else
537
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
538
        raise_exception(TT_TOVF);
539
#endif
540

    
541
    env->psr = 0;
542
#ifdef TARGET_SPARC64
543
    if (!(T0 & 0xffffffff))
544
        env->psr |= PSR_ZERO;
545
    if ((int32_t) T0 < 0)
546
        env->psr |= PSR_NEG;
547
    if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
548
        env->psr |= PSR_CARRY;
549

    
550
    env->xcc = 0;
551
    if (!T0)
552
        env->xcc |= PSR_ZERO;
553
    if ((int64_t) T0 < 0)
554
        env->xcc |= PSR_NEG;
555
    if (T0 < src1)
556
        env->xcc |= PSR_CARRY;
557
#else
558
    if (!T0)
559
        env->psr |= PSR_ZERO;
560
    if ((int32_t) T0 < 0)
561
        env->psr |= PSR_NEG;
562
    if (T0 < src1)
563
        env->psr |= PSR_CARRY;
564
#endif
565
    FORCE_RET();
566
}
567

    
568
void OPPROTO op_sub_T1_T0(void)
569
{
570
    T0 -= T1;
571
}
572

    
573
void OPPROTO op_sub_T1_T0_cc(void)
574
{
575
    target_ulong src1;
576

    
577
    src1 = T0;
578
    T0 -= T1;
579
    env->psr = 0;
580
#ifdef TARGET_SPARC64
581
    if (!(T0 & 0xffffffff))
582
        env->psr |= PSR_ZERO;
583
    if ((int32_t) T0 < 0)
584
        env->psr |= PSR_NEG;
585
    if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
586
        env->psr |= PSR_CARRY;
587
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
588
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
589
        env->psr |= PSR_OVF;
590

    
591
    env->xcc = 0;
592
    if (!T0)
593
        env->xcc |= PSR_ZERO;
594
    if ((int64_t) T0 < 0)
595
        env->xcc |= PSR_NEG;
596
    if (src1 < T1)
597
        env->xcc |= PSR_CARRY;
598
    if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
599
        env->xcc |= PSR_OVF;
600
#else
601
    if (!T0)
602
        env->psr |= PSR_ZERO;
603
    if ((int32_t) T0 < 0)
604
        env->psr |= PSR_NEG;
605
    if (src1 < T1)
606
        env->psr |= PSR_CARRY;
607
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
608
        env->psr |= PSR_OVF;
609
#endif
610
    FORCE_RET();
611
}
612

    
613
void OPPROTO op_subx_T1_T0(void)
614
{
615
    T0 -= T1 + FLAG_SET(PSR_CARRY);
616
}
617

    
618
void OPPROTO op_subx_T1_T0_cc(void)
619
{
620
    target_ulong src1;
621
    src1 = T0;
622
    if (FLAG_SET(PSR_CARRY))
623
    {
624
      T0 -= T1 + 1;
625
      env->psr = 0;
626
#ifdef TARGET_SPARC64
627
      if ((src1 & 0xffffffff) <= (T1 & 0xffffffff))
628
        env->psr |= PSR_CARRY;
629
      env->xcc = 0;
630
      if (src1 <= T1)
631
        env->xcc |= PSR_CARRY;
632
#else
633
      if (src1 <= T1)
634
        env->psr |= PSR_CARRY;
635
#endif
636
    }
637
    else
638
    {
639
      T0 -= T1;
640
      env->psr = 0;
641
#ifdef TARGET_SPARC64
642
      if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
643
        env->psr |= PSR_CARRY;
644
      env->xcc = 0;
645
      if (src1 < T1)
646
        env->xcc |= PSR_CARRY;
647
#else
648
      if (src1 < T1)
649
        env->psr |= PSR_CARRY;
650
#endif
651
    }
652
#ifdef TARGET_SPARC64
653
    if (!(T0 & 0xffffffff))
654
        env->psr |= PSR_ZERO;
655
    if ((int32_t) T0 < 0)
656
        env->psr |= PSR_NEG;
657
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
658
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
659
        env->psr |= PSR_OVF;
660

    
661
    if (!T0)
662
        env->xcc |= PSR_ZERO;
663
    if ((int64_t) T0 < 0)
664
        env->xcc |= PSR_NEG;
665
    if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
666
        env->xcc |= PSR_OVF;
667
#else
668
    if (!T0)
669
        env->psr |= PSR_ZERO;
670
    if ((int32_t) T0 < 0)
671
        env->psr |= PSR_NEG;
672
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
673
        env->psr |= PSR_OVF;
674
#endif
675
    FORCE_RET();
676
}
677

    
678
void OPPROTO op_tsub_T1_T0_cc(void)
679
{
680
    target_ulong src1;
681

    
682
    src1 = T0;
683
    T0 -= T1;
684
    env->psr = 0;
685
#ifdef TARGET_SPARC64
686
    if (!(T0 & 0xffffffff))
687
        env->psr |= PSR_ZERO;
688
    if ((int32_t) T0 < 0)
689
        env->psr |= PSR_NEG;
690
    if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
691
        env->psr |= PSR_CARRY;
692
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
693
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
694
        env->psr |= PSR_OVF;
695
    if ((src1 & 0x03) || (T1 & 0x03))
696
        env->psr |= PSR_OVF;
697

    
698
    env->xcc = 0;
699
    if (!T0)
700
        env->xcc |= PSR_ZERO;
701
    if ((int64_t) T0 < 0)
702
        env->xcc |= PSR_NEG;
703
    if (src1 < T1)
704
        env->xcc |= PSR_CARRY;
705
    if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
706
        env->xcc |= PSR_OVF;
707
#else
708
    if (!T0)
709
        env->psr |= PSR_ZERO;
710
    if ((int32_t) T0 < 0)
711
        env->psr |= PSR_NEG;
712
    if (src1 < T1)
713
        env->psr |= PSR_CARRY;
714
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
715
        env->psr |= PSR_OVF;
716
    if ((src1 & 0x03) || (T1 & 0x03))
717
        env->psr |= PSR_OVF;
718
#endif
719
    FORCE_RET();
720
}
721

    
722
void OPPROTO op_tsub_T1_T0_ccTV(void)
723
{
724
    target_ulong src1;
725

    
726
    if ((T0 & 0x03) || (T1 & 0x03))
727
        raise_exception(TT_TOVF);
728

    
729
    src1 = T0;
730
    T0 -= T1;
731

    
732
#ifdef TARGET_SPARC64
733
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
734
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
735
        raise_exception(TT_TOVF);
736
#else
737
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
738
        raise_exception(TT_TOVF);
739
#endif
740

    
741
    env->psr = 0;
742
#ifdef TARGET_SPARC64
743
    if (!(T0 & 0xffffffff))
744
        env->psr |= PSR_ZERO;
745
    if ((int32_t) T0 < 0)
746
        env->psr |= PSR_NEG;
747
    if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
748
        env->psr |= PSR_CARRY;
749

    
750
    env->xcc = 0;
751
    if (!T0)
752
        env->xcc |= PSR_ZERO;
753
    if ((int64_t) T0 < 0)
754
        env->xcc |= PSR_NEG;
755
    if (src1 < T1)
756
        env->xcc |= PSR_CARRY;
757
#else
758
    if (!T0)
759
        env->psr |= PSR_ZERO;
760
    if ((int32_t) T0 < 0)
761
        env->psr |= PSR_NEG;
762
    if (src1 < T1)
763
        env->psr |= PSR_CARRY;
764
#endif
765
    FORCE_RET();
766
}
767

    
768
void OPPROTO op_and_T1_T0(void)
769
{
770
    T0 &= T1;
771
}
772

    
773
void OPPROTO op_or_T1_T0(void)
774
{
775
    T0 |= T1;
776
}
777

    
778
void OPPROTO op_xor_T1_T0(void)
779
{
780
    T0 ^= T1;
781
}
782

    
783
void OPPROTO op_andn_T1_T0(void)
784
{
785
    T0 &= ~T1;
786
}
787

    
788
void OPPROTO op_orn_T1_T0(void)
789
{
790
    T0 |= ~T1;
791
}
792

    
793
void OPPROTO op_xnor_T1_T0(void)
794
{
795
    T0 ^= ~T1;
796
}
797

    
798
void OPPROTO op_umul_T1_T0(void)
799
{
800
    uint64_t res;
801
    res = (uint64_t) T0 * (uint64_t) T1;
802
#ifdef TARGET_SPARC64
803
    T0 = res;
804
#else
805
    T0 = res & 0xffffffff;
806
#endif
807
    env->y = res >> 32;
808
}
809

    
810
void OPPROTO op_smul_T1_T0(void)
811
{
812
    uint64_t res;
813
    res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
814
#ifdef TARGET_SPARC64
815
    T0 = res;
816
#else
817
    T0 = res & 0xffffffff;
818
#endif
819
    env->y = res >> 32;
820
}
821

    
822
void OPPROTO op_mulscc_T1_T0(void)
823
{
824
    unsigned int b1, N, V, b2;
825
    target_ulong src1;
826

    
827
    N = FLAG_SET(PSR_NEG);
828
    V = FLAG_SET(PSR_OVF);
829
    b1 = N ^ V;
830
    b2 = T0 & 1;
831
    T0 = (b1 << 31) | (T0 >> 1);
832
    if (!(env->y & 1))
833
        T1 = 0;
834
    /* do addition and update flags */
835
    src1 = T0;
836
    T0 += T1;
837
    env->psr = 0;
838
    if (!T0)
839
        env->psr |= PSR_ZERO;
840
    if ((int32_t) T0 < 0)
841
        env->psr |= PSR_NEG;
842
    if (T0 < src1)
843
        env->psr |= PSR_CARRY;
844
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
845
        env->psr |= PSR_OVF;
846
    env->y = (b2 << 31) | (env->y >> 1);
847
    FORCE_RET();
848
}
849

    
850
void OPPROTO op_udiv_T1_T0(void)
851
{
852
    uint64_t x0;
853
    uint32_t x1;
854

    
855
    x0 = T0 | ((uint64_t) (env->y) << 32);
856
    x1 = T1;
857

    
858
    if (x1 == 0) {
859
        raise_exception(TT_DIV_ZERO);
860
    }
861

    
862
    x0 = x0 / x1;
863
    if (x0 > 0xffffffff) {
864
        T0 = 0xffffffff;
865
        T1 = 1;
866
    } else {
867
        T0 = x0;
868
        T1 = 0;
869
    }
870
    FORCE_RET();
871
}
872

    
873
void OPPROTO op_sdiv_T1_T0(void)
874
{
875
    int64_t x0;
876
    int32_t x1;
877

    
878
    x0 = T0 | ((int64_t) (env->y) << 32);
879
    x1 = T1;
880

    
881
    if (x1 == 0) {
882
        raise_exception(TT_DIV_ZERO);
883
    }
884

    
885
    x0 = x0 / x1;
886
    if ((int32_t) x0 != x0) {
887
        T0 = x0 < 0? 0x80000000: 0x7fffffff;
888
        T1 = 1;
889
    } else {
890
        T0 = x0;
891
        T1 = 0;
892
    }
893
    FORCE_RET();
894
}
895

    
896
void OPPROTO op_div_cc(void)
897
{
898
    env->psr = 0;
899
#ifdef TARGET_SPARC64
900
    if (!T0)
901
        env->psr |= PSR_ZERO;
902
    if ((int32_t) T0 < 0)
903
        env->psr |= PSR_NEG;
904
    if (T1)
905
        env->psr |= PSR_OVF;
906

    
907
    env->xcc = 0;
908
    if (!T0)
909
        env->xcc |= PSR_ZERO;
910
    if ((int64_t) T0 < 0)
911
        env->xcc |= PSR_NEG;
912
#else
913
    if (!T0)
914
        env->psr |= PSR_ZERO;
915
    if ((int32_t) T0 < 0)
916
        env->psr |= PSR_NEG;
917
    if (T1)
918
        env->psr |= PSR_OVF;
919
#endif
920
    FORCE_RET();
921
}
922

    
923
#ifdef TARGET_SPARC64
924
void OPPROTO op_mulx_T1_T0(void)
925
{
926
    T0 *= T1;
927
    FORCE_RET();
928
}
929

    
930
void OPPROTO op_udivx_T1_T0(void)
931
{
932
    if (T1 == 0) {
933
        raise_exception(TT_DIV_ZERO);
934
    }
935
    T0 /= T1;
936
    FORCE_RET();
937
}
938

    
939
void OPPROTO op_sdivx_T1_T0(void)
940
{
941
    if (T1 == 0) {
942
        raise_exception(TT_DIV_ZERO);
943
    }
944
    if (T0 == INT64_MIN && T1 == -1)
945
        T0 = INT64_MIN;
946
    else
947
        T0 /= (target_long) T1;
948
    FORCE_RET();
949
}
950
#endif
951

    
952
void OPPROTO op_logic_T0_cc(void)
953
{
954
    env->psr = 0;
955
#ifdef TARGET_SPARC64
956
    if (!(T0 & 0xffffffff))
957
        env->psr |= PSR_ZERO;
958
    if ((int32_t) T0 < 0)
959
        env->psr |= PSR_NEG;
960

    
961
    env->xcc = 0;
962
    if (!T0)
963
        env->xcc |= PSR_ZERO;
964
    if ((int64_t) T0 < 0)
965
        env->xcc |= PSR_NEG;
966
#else
967
    if (!T0)
968
        env->psr |= PSR_ZERO;
969
    if ((int32_t) T0 < 0)
970
        env->psr |= PSR_NEG;
971
#endif
972
    FORCE_RET();
973
}
974

    
975
void OPPROTO op_sll(void)
976
{
977
    T0 <<= (T1 & 0x1f);
978
}
979

    
980
#ifdef TARGET_SPARC64
981
void OPPROTO op_sllx(void)
982
{
983
    T0 <<= (T1 & 0x3f);
984
}
985

    
986
void OPPROTO op_srl(void)
987
{
988
    T0 = (T0 & 0xffffffff) >> (T1 & 0x1f);
989
}
990

    
991
void OPPROTO op_srlx(void)
992
{
993
    T0 >>= (T1 & 0x3f);
994
}
995

    
996
void OPPROTO op_sra(void)
997
{
998
    T0 = ((int32_t) (T0 & 0xffffffff)) >> (T1 & 0x1f);
999
}
1000

    
1001
void OPPROTO op_srax(void)
1002
{
1003
    T0 = ((int64_t) T0) >> (T1 & 0x3f);
1004
}
1005
#else
1006
void OPPROTO op_srl(void)
1007
{
1008
    T0 >>= (T1 & 0x1f);
1009
}
1010

    
1011
void OPPROTO op_sra(void)
1012
{
1013
    T0 = ((int32_t) T0) >> (T1 & 0x1f);
1014
}
1015
#endif
1016

    
1017
/* Load and store */
1018
#define MEMSUFFIX _raw
1019
#include "op_mem.h"
1020
#if !defined(CONFIG_USER_ONLY)
1021
#define MEMSUFFIX _user
1022
#include "op_mem.h"
1023

    
1024
#define MEMSUFFIX _kernel
1025
#include "op_mem.h"
1026

    
1027
#ifdef TARGET_SPARC64
1028
#define MEMSUFFIX _hypv
1029
#include "op_mem.h"
1030
#endif
1031
#endif
1032

    
1033
void OPPROTO op_ldfsr(void)
1034
{
1035
    PUT_FSR32(env, *((uint32_t *) &FT0));
1036
    helper_ldfsr();
1037
}
1038

    
1039
void OPPROTO op_stfsr(void)
1040
{
1041
    *((uint32_t *) &FT0) = GET_FSR32(env);
1042
}
1043

    
1044
#ifndef TARGET_SPARC64
1045
void OPPROTO op_rdpsr(void)
1046
{
1047
    do_rdpsr();
1048
}
1049

    
1050
void OPPROTO op_wrpsr(void)
1051
{
1052
    do_wrpsr();
1053
    FORCE_RET();
1054
}
1055

    
1056
void OPPROTO op_wrwim(void)
1057
{
1058
#if NWINDOWS == 32
1059
    env->wim = T0;
1060
#else
1061
    env->wim = T0 & ((1 << NWINDOWS) - 1);
1062
#endif
1063
}
1064

    
1065
void OPPROTO op_rett(void)
1066
{
1067
    helper_rett();
1068
    FORCE_RET();
1069
}
1070

    
1071
/* XXX: use another pointer for %iN registers to avoid slow wrapping
1072
   handling ? */
1073
void OPPROTO op_save(void)
1074
{
1075
    uint32_t cwp;
1076
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
1077
    if (env->wim & (1 << cwp)) {
1078
        raise_exception(TT_WIN_OVF);
1079
    }
1080
    set_cwp(cwp);
1081
    FORCE_RET();
1082
}
1083

    
1084
void OPPROTO op_restore(void)
1085
{
1086
    uint32_t cwp;
1087
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
1088
    if (env->wim & (1 << cwp)) {
1089
        raise_exception(TT_WIN_UNF);
1090
    }
1091
    set_cwp(cwp);
1092
    FORCE_RET();
1093
}
1094
#else
1095
void OPPROTO op_rdccr(void)
1096
{
1097
    T0 = GET_CCR(env);
1098
}
1099

    
1100
void OPPROTO op_wrccr(void)
1101
{
1102
    PUT_CCR(env, T0);
1103
}
1104

    
1105
void OPPROTO op_rdtick(void)
1106
{
1107
    T0 = do_tick_get_count(env->tick);
1108
}
1109

    
1110
void OPPROTO op_wrtick(void)
1111
{
1112
    do_tick_set_count(env->tick, T0);
1113
}
1114

    
1115
void OPPROTO op_wrtick_cmpr(void)
1116
{
1117
    do_tick_set_limit(env->tick, T0);
1118
}
1119

    
1120
void OPPROTO op_rdstick(void)
1121
{
1122
    T0 = do_tick_get_count(env->stick);
1123
}
1124

    
1125
void OPPROTO op_wrstick(void)
1126
{
1127
    do_tick_set_count(env->stick, T0);
1128
    do_tick_set_count(env->hstick, T0);
1129
}
1130

    
1131
void OPPROTO op_wrstick_cmpr(void)
1132
{
1133
    do_tick_set_limit(env->stick, T0);
1134
}
1135

    
1136
void OPPROTO op_wrhstick_cmpr(void)
1137
{
1138
    do_tick_set_limit(env->hstick, T0);
1139
}
1140

    
1141
void OPPROTO op_rdtpc(void)
1142
{
1143
    T0 = env->tpc[env->tl];
1144
}
1145

    
1146
void OPPROTO op_wrtpc(void)
1147
{
1148
    env->tpc[env->tl] = T0;
1149
}
1150

    
1151
void OPPROTO op_rdtnpc(void)
1152
{
1153
    T0 = env->tnpc[env->tl];
1154
}
1155

    
1156
void OPPROTO op_wrtnpc(void)
1157
{
1158
    env->tnpc[env->tl] = T0;
1159
}
1160

    
1161
void OPPROTO op_rdtstate(void)
1162
{
1163
    T0 = env->tstate[env->tl];
1164
}
1165

    
1166
void OPPROTO op_wrtstate(void)
1167
{
1168
    env->tstate[env->tl] = T0;
1169
}
1170

    
1171
void OPPROTO op_rdtt(void)
1172
{
1173
    T0 = env->tt[env->tl];
1174
}
1175

    
1176
void OPPROTO op_wrtt(void)
1177
{
1178
    env->tt[env->tl] = T0;
1179
}
1180

    
1181
void OPPROTO op_rdpstate(void)
1182
{
1183
    T0 = env->pstate;
1184
}
1185

    
1186
void OPPROTO op_wrpstate(void)
1187
{
1188
    do_wrpstate();
1189
}
1190

    
1191
// CWP handling is reversed in V9, but we still use the V8 register
1192
// order.
1193
void OPPROTO op_rdcwp(void)
1194
{
1195
    T0 = GET_CWP64(env);
1196
}
1197

    
1198
void OPPROTO op_wrcwp(void)
1199
{
1200
    PUT_CWP64(env, T0);
1201
}
1202

    
1203
/* XXX: use another pointer for %iN registers to avoid slow wrapping
1204
   handling ? */
1205
void OPPROTO op_save(void)
1206
{
1207
    uint32_t cwp;
1208
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
1209
    if (env->cansave == 0) {
1210
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
1211
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1212
                                    ((env->wstate & 0x7) << 2)));
1213
    } else {
1214
        if (env->cleanwin - env->canrestore == 0) {
1215
            // XXX Clean windows without trap
1216
            raise_exception(TT_CLRWIN);
1217
        } else {
1218
            env->cansave--;
1219
            env->canrestore++;
1220
            set_cwp(cwp);
1221
        }
1222
    }
1223
    FORCE_RET();
1224
}
1225

    
1226
void OPPROTO op_restore(void)
1227
{
1228
    uint32_t cwp;
1229
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
1230
    if (env->canrestore == 0) {
1231
        raise_exception(TT_FILL | (env->otherwin != 0 ?
1232
                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1233
                                   ((env->wstate & 0x7) << 2)));
1234
    } else {
1235
        env->cansave++;
1236
        env->canrestore--;
1237
        set_cwp(cwp);
1238
    }
1239
    FORCE_RET();
1240
}
1241
#endif
1242

    
1243
void OPPROTO op_exception(void)
1244
{
1245
    env->exception_index = PARAM1;
1246
    cpu_loop_exit();
1247
}
1248

    
1249
void OPPROTO op_trap_T0(void)
1250
{
1251
    env->exception_index = TT_TRAP + (T0 & 0x7f);
1252
    cpu_loop_exit();
1253
}
1254

    
1255
void OPPROTO op_trapcc_T0(void)
1256
{
1257
    if (T2) {
1258
        env->exception_index = TT_TRAP + (T0 & 0x7f);
1259
        cpu_loop_exit();
1260
    }
1261
    FORCE_RET();
1262
}
1263

    
1264
void OPPROTO op_fpexception_im(void)
1265
{
1266
    env->exception_index = TT_FP_EXCP;
1267
    env->fsr &= ~FSR_FTT_MASK;
1268
    env->fsr |= PARAM1;
1269
    cpu_loop_exit();
1270
    FORCE_RET();
1271
}
1272

    
1273
void OPPROTO op_debug(void)
1274
{
1275
    helper_debug();
1276
}
1277

    
1278
void OPPROTO op_exit_tb(void)
1279
{
1280
    EXIT_TB();
1281
}
1282

    
1283
void OPPROTO op_eval_ba(void)
1284
{
1285
    T2 = 1;
1286
}
1287

    
1288
void OPPROTO op_eval_be(void)
1289
{
1290
    T2 = FLAG_SET(PSR_ZERO);
1291
}
1292

    
1293
void OPPROTO op_eval_ble(void)
1294
{
1295
    target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1296

    
1297
    T2 = Z | (N ^ V);
1298
}
1299

    
1300
void OPPROTO op_eval_bl(void)
1301
{
1302
    target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1303

    
1304
    T2 = N ^ V;
1305
}
1306

    
1307
void OPPROTO op_eval_bleu(void)
1308
{
1309
    target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1310

    
1311
    T2 = C | Z;
1312
}
1313

    
1314
void OPPROTO op_eval_bcs(void)
1315
{
1316
    T2 = FLAG_SET(PSR_CARRY);
1317
}
1318

    
1319
void OPPROTO op_eval_bvs(void)
1320
{
1321
    T2 = FLAG_SET(PSR_OVF);
1322
}
1323

    
1324
void OPPROTO op_eval_bn(void)
1325
{
1326
    T2 = 0;
1327
}
1328

    
1329
void OPPROTO op_eval_bneg(void)
1330
{
1331
    T2 = FLAG_SET(PSR_NEG);
1332
}
1333

    
1334
void OPPROTO op_eval_bne(void)
1335
{
1336
    T2 = !FLAG_SET(PSR_ZERO);
1337
}
1338

    
1339
void OPPROTO op_eval_bg(void)
1340
{
1341
    target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1342

    
1343
    T2 = !(Z | (N ^ V));
1344
}
1345

    
1346
void OPPROTO op_eval_bge(void)
1347
{
1348
    target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1349

    
1350
    T2 = !(N ^ V);
1351
}
1352

    
1353
void OPPROTO op_eval_bgu(void)
1354
{
1355
    target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1356

    
1357
    T2 = !(C | Z);
1358
}
1359

    
1360
void OPPROTO op_eval_bcc(void)
1361
{
1362
    T2 = !FLAG_SET(PSR_CARRY);
1363
}
1364

    
1365
void OPPROTO op_eval_bpos(void)
1366
{
1367
    T2 = !FLAG_SET(PSR_NEG);
1368
}
1369

    
1370
void OPPROTO op_eval_bvc(void)
1371
{
1372
    T2 = !FLAG_SET(PSR_OVF);
1373
}
1374

    
1375
#ifdef TARGET_SPARC64
1376
void OPPROTO op_eval_xbe(void)
1377
{
1378
    T2 = XFLAG_SET(PSR_ZERO);
1379
}
1380

    
1381
void OPPROTO op_eval_xble(void)
1382
{
1383
    target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1384

    
1385
    T2 = Z | (N ^ V);
1386
}
1387

    
1388
void OPPROTO op_eval_xbl(void)
1389
{
1390
    target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1391

    
1392
    T2 = N ^ V;
1393
}
1394

    
1395
void OPPROTO op_eval_xbleu(void)
1396
{
1397
    target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1398

    
1399
    T2 = C | Z;
1400
}
1401

    
1402
void OPPROTO op_eval_xbcs(void)
1403
{
1404
    T2 = XFLAG_SET(PSR_CARRY);
1405
}
1406

    
1407
void OPPROTO op_eval_xbvs(void)
1408
{
1409
    T2 = XFLAG_SET(PSR_OVF);
1410
}
1411

    
1412
void OPPROTO op_eval_xbneg(void)
1413
{
1414
    T2 = XFLAG_SET(PSR_NEG);
1415
}
1416

    
1417
void OPPROTO op_eval_xbne(void)
1418
{
1419
    T2 = !XFLAG_SET(PSR_ZERO);
1420
}
1421

    
1422
void OPPROTO op_eval_xbg(void)
1423
{
1424
    target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1425

    
1426
    T2 = !(Z | (N ^ V));
1427
}
1428

    
1429
void OPPROTO op_eval_xbge(void)
1430
{
1431
    target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1432

    
1433
    T2 = !(N ^ V);
1434
}
1435

    
1436
void OPPROTO op_eval_xbgu(void)
1437
{
1438
    target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1439

    
1440
    T2 = !(C | Z);
1441
}
1442

    
1443
void OPPROTO op_eval_xbcc(void)
1444
{
1445
    T2 = !XFLAG_SET(PSR_CARRY);
1446
}
1447

    
1448
void OPPROTO op_eval_xbpos(void)
1449
{
1450
    T2 = !XFLAG_SET(PSR_NEG);
1451
}
1452

    
1453
void OPPROTO op_eval_xbvc(void)
1454
{
1455
    T2 = !XFLAG_SET(PSR_OVF);
1456
}
1457
#endif
1458

    
1459
#define FCC
1460
#define FFLAG_SET(x) (env->fsr & x? 1: 0)
1461
#include "fbranch_template.h"
1462

    
1463
#ifdef TARGET_SPARC64
1464
#define FCC _fcc1
1465
#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
1466
#include "fbranch_template.h"
1467
#define FCC _fcc2
1468
#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
1469
#include "fbranch_template.h"
1470
#define FCC _fcc3
1471
#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
1472
#include "fbranch_template.h"
1473
#endif
1474

    
1475
#ifdef TARGET_SPARC64
1476
void OPPROTO op_eval_brz(void)
1477
{
1478
    T2 = (T0 == 0);
1479
}
1480

    
1481
void OPPROTO op_eval_brnz(void)
1482
{
1483
    T2 = (T0 != 0);
1484
}
1485

    
1486
void OPPROTO op_eval_brlz(void)
1487
{
1488
    T2 = ((int64_t)T0 < 0);
1489
}
1490

    
1491
void OPPROTO op_eval_brlez(void)
1492
{
1493
    T2 = ((int64_t)T0 <= 0);
1494
}
1495

    
1496
void OPPROTO op_eval_brgz(void)
1497
{
1498
    T2 = ((int64_t)T0 > 0);
1499
}
1500

    
1501
void OPPROTO op_eval_brgez(void)
1502
{
1503
    T2 = ((int64_t)T0 >= 0);
1504
}
1505

    
1506
void OPPROTO op_jmp_im64(void)
1507
{
1508
    env->pc = PARAMQ1;
1509
}
1510

    
1511
void OPPROTO op_movq_npc_im64(void)
1512
{
1513
    env->npc = PARAMQ1;
1514
}
1515
#endif
1516

    
1517
void OPPROTO op_jmp_im(void)
1518
{
1519
    env->pc = (uint32_t)PARAM1;
1520
}
1521

    
1522
void OPPROTO op_movl_npc_im(void)
1523
{
1524
    env->npc = (uint32_t)PARAM1;
1525
}
1526

    
1527
void OPPROTO op_movl_npc_T0(void)
1528
{
1529
    env->npc = T0;
1530
}
1531

    
1532
void OPPROTO op_mov_pc_npc(void)
1533
{
1534
    env->pc = env->npc;
1535
}
1536

    
1537
void OPPROTO op_next_insn(void)
1538
{
1539
    env->pc = env->npc;
1540
    env->npc = env->npc + 4;
1541
}
1542

    
1543
void OPPROTO op_goto_tb0(void)
1544
{
1545
    GOTO_TB(op_goto_tb0, PARAM1, 0);
1546
}
1547

    
1548
void OPPROTO op_goto_tb1(void)
1549
{
1550
    GOTO_TB(op_goto_tb1, PARAM1, 1);
1551
}
1552

    
1553
void OPPROTO op_jmp_label(void)
1554
{
1555
    GOTO_LABEL_PARAM(1);
1556
}
1557

    
1558
void OPPROTO op_jnz_T2_label(void)
1559
{
1560
    if (T2)
1561
        GOTO_LABEL_PARAM(1);
1562
    FORCE_RET();
1563
}
1564

    
1565
void OPPROTO op_jz_T2_label(void)
1566
{
1567
    if (!T2)
1568
        GOTO_LABEL_PARAM(1);
1569
    FORCE_RET();
1570
}
1571

    
1572
void OPPROTO op_flush_T0(void)
1573
{
1574
    helper_flush(T0);
1575
}
1576

    
1577
void OPPROTO op_clear_ieee_excp_and_FTT(void)
1578
{
1579
    env->fsr &= ~(FSR_FTT_MASK | FSR_CEXC_MASK);;
1580
}
1581

    
1582
#define F_OP(name, p) void OPPROTO op_f##name##p(void)
1583

    
1584
#if defined(CONFIG_USER_ONLY)
1585
#define F_BINOP(name)                                           \
1586
    F_OP(name, s)                                               \
1587
    {                                                           \
1588
        set_float_exception_flags(0, &env->fp_status);          \
1589
        FT0 = float32_ ## name (FT0, FT1, &env->fp_status);     \
1590
        check_ieee_exceptions();                                \
1591
    }                                                           \
1592
    F_OP(name, d)                                               \
1593
    {                                                           \
1594
        set_float_exception_flags(0, &env->fp_status);          \
1595
        DT0 = float64_ ## name (DT0, DT1, &env->fp_status);     \
1596
        check_ieee_exceptions();                                \
1597
    }                                                           \
1598
    F_OP(name, q)                                               \
1599
    {                                                           \
1600
        set_float_exception_flags(0, &env->fp_status);          \
1601
        QT0 = float128_ ## name (QT0, QT1, &env->fp_status);    \
1602
        check_ieee_exceptions();                                \
1603
    }
1604
#else
1605
#define F_BINOP(name)                                           \
1606
    F_OP(name, s)                                               \
1607
    {                                                           \
1608
        set_float_exception_flags(0, &env->fp_status);          \
1609
        FT0 = float32_ ## name (FT0, FT1, &env->fp_status);     \
1610
        check_ieee_exceptions();                                \
1611
    }                                                           \
1612
    F_OP(name, d)                                               \
1613
    {                                                           \
1614
        set_float_exception_flags(0, &env->fp_status);          \
1615
        DT0 = float64_ ## name (DT0, DT1, &env->fp_status);     \
1616
        check_ieee_exceptions();                                \
1617
    }
1618
#endif
1619

    
1620
F_BINOP(add);
1621
F_BINOP(sub);
1622
F_BINOP(mul);
1623
F_BINOP(div);
1624
#undef F_BINOP
1625

    
1626
void OPPROTO op_fsmuld(void)
1627
{
1628
    set_float_exception_flags(0, &env->fp_status);
1629
    DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status),
1630
                      float32_to_float64(FT1, &env->fp_status),
1631
                      &env->fp_status);
1632
    check_ieee_exceptions();
1633
}
1634

    
1635
#if defined(CONFIG_USER_ONLY)
1636
void OPPROTO op_fdmulq(void)
1637
{
1638
    set_float_exception_flags(0, &env->fp_status);
1639
    QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status),
1640
                       float64_to_float128(DT1, &env->fp_status),
1641
                       &env->fp_status);
1642
    check_ieee_exceptions();
1643
}
1644
#endif
1645

    
1646
#if defined(CONFIG_USER_ONLY)
1647
#define F_HELPER(name)    \
1648
    F_OP(name, s)         \
1649
    {                     \
1650
        do_f##name##s();  \
1651
    }                     \
1652
    F_OP(name, d)         \
1653
    {                     \
1654
        do_f##name##d();  \
1655
    }                     \
1656
    F_OP(name, q)         \
1657
    {                     \
1658
        do_f##name##q();  \
1659
    }
1660
#else
1661
#define F_HELPER(name)    \
1662
    F_OP(name, s)         \
1663
    {                     \
1664
        do_f##name##s();  \
1665
    }                     \
1666
    F_OP(name, d)         \
1667
    {                     \
1668
        do_f##name##d();  \
1669
    }
1670
#endif
1671

    
1672
F_HELPER(sqrt);
1673

    
1674
F_OP(neg, s)
1675
{
1676
    FT0 = float32_chs(FT1);
1677
}
1678

    
1679
F_OP(abs, s)
1680
{
1681
    do_fabss();
1682
}
1683

    
1684
F_HELPER(cmp);
1685
F_HELPER(cmpe);
1686

    
1687
#ifdef TARGET_SPARC64
1688
F_OP(neg, d)
1689
{
1690
    DT0 = float64_chs(DT1);
1691
}
1692

    
1693
F_OP(abs, d)
1694
{
1695
    do_fabsd();
1696
}
1697

    
1698
#if defined(CONFIG_USER_ONLY)
1699
F_OP(neg, q)
1700
{
1701
    QT0 = float128_chs(QT1);
1702
}
1703

    
1704
F_OP(abs, q)
1705
{
1706
    do_fabsd();
1707
}
1708
#endif
1709

    
1710
void OPPROTO op_fcmps_fcc1(void)
1711
{
1712
    do_fcmps_fcc1();
1713
}
1714

    
1715
void OPPROTO op_fcmpd_fcc1(void)
1716
{
1717
    do_fcmpd_fcc1();
1718
}
1719

    
1720
void OPPROTO op_fcmps_fcc2(void)
1721
{
1722
    do_fcmps_fcc2();
1723
}
1724

    
1725
void OPPROTO op_fcmpd_fcc2(void)
1726
{
1727
    do_fcmpd_fcc2();
1728
}
1729

    
1730
void OPPROTO op_fcmps_fcc3(void)
1731
{
1732
    do_fcmps_fcc3();
1733
}
1734

    
1735
void OPPROTO op_fcmpd_fcc3(void)
1736
{
1737
    do_fcmpd_fcc3();
1738
}
1739

    
1740
void OPPROTO op_fcmpes_fcc1(void)
1741
{
1742
    do_fcmpes_fcc1();
1743
}
1744

    
1745
void OPPROTO op_fcmped_fcc1(void)
1746
{
1747
    do_fcmped_fcc1();
1748
}
1749

    
1750
void OPPROTO op_fcmpes_fcc2(void)
1751
{
1752
    do_fcmpes_fcc2();
1753
}
1754

    
1755
void OPPROTO op_fcmped_fcc2(void)
1756
{
1757
    do_fcmped_fcc2();
1758
}
1759

    
1760
void OPPROTO op_fcmpes_fcc3(void)
1761
{
1762
    do_fcmpes_fcc3();
1763
}
1764

    
1765
void OPPROTO op_fcmped_fcc3(void)
1766
{
1767
    do_fcmped_fcc3();
1768
}
1769

    
1770
#if defined(CONFIG_USER_ONLY)
1771
void OPPROTO op_fcmpq_fcc1(void)
1772
{
1773
    do_fcmpq_fcc1();
1774
}
1775

    
1776
void OPPROTO op_fcmpq_fcc2(void)
1777
{
1778
    do_fcmpq_fcc2();
1779
}
1780

    
1781
void OPPROTO op_fcmpq_fcc3(void)
1782
{
1783
    do_fcmpq_fcc3();
1784
}
1785

    
1786
void OPPROTO op_fcmpeq_fcc1(void)
1787
{
1788
    do_fcmpeq_fcc1();
1789
}
1790

    
1791
void OPPROTO op_fcmpeq_fcc2(void)
1792
{
1793
    do_fcmpeq_fcc2();
1794
}
1795

    
1796
void OPPROTO op_fcmpeq_fcc3(void)
1797
{
1798
    do_fcmpeq_fcc3();
1799
}
1800
#endif
1801

    
1802
#endif
1803

    
1804
/* Integer to float conversion.  */
1805
#ifdef USE_INT_TO_FLOAT_HELPERS
1806
F_HELPER(ito);
1807
#ifdef TARGET_SPARC64
1808
F_HELPER(xto);
1809
#endif
1810
#else
1811
F_OP(ito, s)
1812
{
1813
    set_float_exception_flags(0, &env->fp_status);
1814
    FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
1815
    check_ieee_exceptions();
1816
}
1817

    
1818
F_OP(ito, d)
1819
{
1820
    set_float_exception_flags(0, &env->fp_status);
1821
    DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
1822
    check_ieee_exceptions();
1823
}
1824

    
1825
#if defined(CONFIG_USER_ONLY)
1826
F_OP(ito, q)
1827
{
1828
    set_float_exception_flags(0, &env->fp_status);
1829
    QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
1830
    check_ieee_exceptions();
1831
}
1832
#endif
1833

    
1834
#ifdef TARGET_SPARC64
1835
F_OP(xto, s)
1836
{
1837
    set_float_exception_flags(0, &env->fp_status);
1838
    FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
1839
    check_ieee_exceptions();
1840
}
1841

    
1842
F_OP(xto, d)
1843
{
1844
    set_float_exception_flags(0, &env->fp_status);
1845
    DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
1846
    check_ieee_exceptions();
1847
}
1848
#if defined(CONFIG_USER_ONLY)
1849
F_OP(xto, q)
1850
{
1851
    set_float_exception_flags(0, &env->fp_status);
1852
    QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
1853
    check_ieee_exceptions();
1854
}
1855
#endif
1856
#endif
1857
#endif
1858
#undef F_HELPER
1859

    
1860
/* floating point conversion */
1861
void OPPROTO op_fdtos(void)
1862
{
1863
    set_float_exception_flags(0, &env->fp_status);
1864
    FT0 = float64_to_float32(DT1, &env->fp_status);
1865
    check_ieee_exceptions();
1866
}
1867

    
1868
void OPPROTO op_fstod(void)
1869
{
1870
    set_float_exception_flags(0, &env->fp_status);
1871
    DT0 = float32_to_float64(FT1, &env->fp_status);
1872
    check_ieee_exceptions();
1873
}
1874

    
1875
#if defined(CONFIG_USER_ONLY)
1876
void OPPROTO op_fqtos(void)
1877
{
1878
    set_float_exception_flags(0, &env->fp_status);
1879
    FT0 = float128_to_float32(QT1, &env->fp_status);
1880
    check_ieee_exceptions();
1881
}
1882

    
1883
void OPPROTO op_fstoq(void)
1884
{
1885
    set_float_exception_flags(0, &env->fp_status);
1886
    QT0 = float32_to_float128(FT1, &env->fp_status);
1887
    check_ieee_exceptions();
1888
}
1889

    
1890
void OPPROTO op_fqtod(void)
1891
{
1892
    set_float_exception_flags(0, &env->fp_status);
1893
    DT0 = float128_to_float64(QT1, &env->fp_status);
1894
    check_ieee_exceptions();
1895
}
1896

    
1897
void OPPROTO op_fdtoq(void)
1898
{
1899
    set_float_exception_flags(0, &env->fp_status);
1900
    QT0 = float64_to_float128(DT1, &env->fp_status);
1901
    check_ieee_exceptions();
1902
}
1903
#endif
1904

    
1905
/* Float to integer conversion.  */
1906
void OPPROTO op_fstoi(void)
1907
{
1908
    set_float_exception_flags(0, &env->fp_status);
1909
    *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status);
1910
    check_ieee_exceptions();
1911
}
1912

    
1913
void OPPROTO op_fdtoi(void)
1914
{
1915
    set_float_exception_flags(0, &env->fp_status);
1916
    *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
1917
    check_ieee_exceptions();
1918
}
1919

    
1920
#if defined(CONFIG_USER_ONLY)
1921
void OPPROTO op_fqtoi(void)
1922
{
1923
    set_float_exception_flags(0, &env->fp_status);
1924
    *((int32_t *)&FT0) = float128_to_int32_round_to_zero(QT1, &env->fp_status);
1925
    check_ieee_exceptions();
1926
}
1927
#endif
1928

    
1929
#ifdef TARGET_SPARC64
1930
void OPPROTO op_fstox(void)
1931
{
1932
    set_float_exception_flags(0, &env->fp_status);
1933
    *((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status);
1934
    check_ieee_exceptions();
1935
}
1936

    
1937
void OPPROTO op_fdtox(void)
1938
{
1939
    set_float_exception_flags(0, &env->fp_status);
1940
    *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
1941
    check_ieee_exceptions();
1942
}
1943

    
1944
#if defined(CONFIG_USER_ONLY)
1945
void OPPROTO op_fqtox(void)
1946
{
1947
    set_float_exception_flags(0, &env->fp_status);
1948
    *((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status);
1949
    check_ieee_exceptions();
1950
}
1951
#endif
1952

    
1953
void OPPROTO op_fmovs_cc(void)
1954
{
1955
    if (T2)
1956
        FT0 = FT1;
1957
}
1958

    
1959
void OPPROTO op_fmovd_cc(void)
1960
{
1961
    if (T2)
1962
        DT0 = DT1;
1963
}
1964

    
1965
#if defined(CONFIG_USER_ONLY)
1966
void OPPROTO op_fmovq_cc(void)
1967
{
1968
    if (T2)
1969
        QT0 = QT1;
1970
}
1971
#endif
1972

    
1973
void OPPROTO op_mov_cc(void)
1974
{
1975
    if (T2)
1976
        T0 = T1;
1977
}
1978

    
1979
void OPPROTO op_flushw(void)
1980
{
1981
    if (env->cansave != NWINDOWS - 2) {
1982
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
1983
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1984
                                    ((env->wstate & 0x7) << 2)));
1985
    }
1986
}
1987

    
1988
void OPPROTO op_saved(void)
1989
{
1990
    env->cansave++;
1991
    if (env->otherwin == 0)
1992
        env->canrestore--;
1993
    else
1994
        env->otherwin--;
1995
    FORCE_RET();
1996
}
1997

    
1998
void OPPROTO op_restored(void)
1999
{
2000
    env->canrestore++;
2001
    if (env->cleanwin < NWINDOWS - 1)
2002
        env->cleanwin++;
2003
    if (env->otherwin == 0)
2004
        env->cansave--;
2005
    else
2006
        env->otherwin--;
2007
    FORCE_RET();
2008
}
2009

    
2010
void OPPROTO op_popc(void)
2011
{
2012
    do_popc();
2013
}
2014

    
2015
void OPPROTO op_done(void)
2016
{
2017
    do_done();
2018
}
2019

    
2020
void OPPROTO op_retry(void)
2021
{
2022
    do_retry();
2023
}
2024

    
2025
void OPPROTO op_sir(void)
2026
{
2027
    T0 = 0;  // XXX
2028
}
2029

    
2030
void OPPROTO op_ld_asi_reg()
2031
{
2032
    T0 += PARAM1;
2033
    helper_ld_asi(env->asi, PARAM2, PARAM3);
2034
}
2035

    
2036
void OPPROTO op_st_asi_reg()
2037
{
2038
    T0 += PARAM1;
2039
    helper_st_asi(env->asi, PARAM2);
2040
}
2041

    
2042
void OPPROTO op_ldf_asi_reg()
2043
{
2044
    T0 += PARAM1;
2045
    helper_ldf_asi(env->asi, PARAM2, PARAM3);
2046
}
2047

    
2048
void OPPROTO op_stf_asi_reg()
2049
{
2050
    T0 += PARAM1;
2051
    helper_stf_asi(env->asi, PARAM2, PARAM3);
2052
}
2053

    
2054
void OPPROTO op_ldf_asi()
2055
{
2056
    helper_ldf_asi(PARAM1, PARAM2, PARAM3);
2057
}
2058

    
2059
void OPPROTO op_stf_asi()
2060
{
2061
    helper_stf_asi(PARAM1, PARAM2, PARAM3);
2062
}
2063

    
2064
void OPPROTO op_ldstub_asi_reg()             /* XXX: should be atomically */
2065
{
2066
    target_ulong tmp;
2067

    
2068
    T0 += PARAM1;
2069
    helper_ld_asi(env->asi, 1, 0);
2070
    tmp = T1;
2071
    T1 = 0xff;
2072
    helper_st_asi(env->asi, 1);
2073
    T1 = tmp;
2074
}
2075

    
2076
void OPPROTO op_swap_asi_reg()               /* XXX: should be atomically */
2077
{
2078
    target_ulong tmp1, tmp2;
2079

    
2080
    T0 += PARAM1;
2081
    tmp1 = T1;
2082
    helper_ld_asi(env->asi, 4, 0);
2083
    tmp2 = T1;
2084
    T1 = tmp1;
2085
    helper_st_asi(env->asi, 4);
2086
    T1 = tmp2;
2087
}
2088

    
2089
void OPPROTO op_ldda_asi()
2090
{
2091
    helper_ld_asi(PARAM1, 8, 0);
2092
    T0 = T1 & 0xffffffffUL;
2093
    T1 >>= 32;
2094
}
2095

    
2096
void OPPROTO op_ldda_asi_reg()
2097
{
2098
    T0 += PARAM1;
2099
    helper_ld_asi(env->asi, 8, 0);
2100
    T0 = T1 & 0xffffffffUL;
2101
    T1 >>= 32;
2102
}
2103

    
2104
void OPPROTO op_stda_asi()
2105
{
2106
    T1 <<= 32;
2107
    T1 += T2 & 0xffffffffUL;
2108
    helper_st_asi(PARAM1, 8);
2109
}
2110

    
2111
void OPPROTO op_stda_asi_reg()
2112
{
2113
    T0 += PARAM1;
2114
    T1 <<= 32;
2115
    T1 += T2 & 0xffffffffUL;
2116
    helper_st_asi(env->asi, 8);
2117
}
2118

    
2119
void OPPROTO op_cas_asi()                    /* XXX: should be atomically */
2120
{
2121
    target_ulong tmp;
2122

    
2123
    tmp = T1 & 0xffffffffUL;
2124
    helper_ld_asi(PARAM1, 4, 0);
2125
    if (tmp == T1) {
2126
        tmp = T1;
2127
        T1 = T2 & 0xffffffffUL;
2128
        helper_st_asi(PARAM1, 4);
2129
        T1 = tmp;
2130
    }
2131
    T1 &= 0xffffffffUL;
2132
}
2133

    
2134
void OPPROTO op_cas_asi_reg()                /* XXX: should be atomically */
2135
{
2136
    target_ulong tmp;
2137

    
2138
    T0 += PARAM1;
2139
    tmp = T1 & 0xffffffffUL;
2140
    helper_ld_asi(env->asi, 4, 0);
2141
    if (tmp == T1) {
2142
        tmp = T1;
2143
        T1 = T2 & 0xffffffffUL;
2144
        helper_st_asi(env->asi, 4);
2145
        T1 = tmp;
2146
    }
2147
    T1 &= 0xffffffffUL;
2148
}
2149

    
2150
void OPPROTO op_casx_asi()                   /* XXX: should be atomically */
2151
{
2152
    target_ulong tmp;
2153

    
2154
    tmp = T1;
2155
    helper_ld_asi(PARAM1, 8, 0);
2156
    if (tmp == T1) {
2157
        tmp = T1;
2158
        T1 = T2;
2159
        helper_st_asi(PARAM1, 8);
2160
        T1 = tmp;
2161
    }
2162
}
2163

    
2164
void OPPROTO op_casx_asi_reg()               /* XXX: should be atomically */
2165
{
2166
    target_ulong tmp;
2167

    
2168
    T0 += PARAM1;
2169
    tmp = T1;
2170
    helper_ld_asi(env->asi, 8, 0);
2171
    if (tmp == T1) {
2172
        tmp = T1;
2173
        T1 = T2;
2174
        helper_st_asi(env->asi, 8);
2175
        T1 = tmp;
2176
    }
2177
}
2178
#endif
2179

    
2180
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
2181
void OPPROTO op_ld_asi()
2182
{
2183
    helper_ld_asi(PARAM1, PARAM2, PARAM3);
2184
}
2185

    
2186
void OPPROTO op_st_asi()
2187
{
2188
    helper_st_asi(PARAM1, PARAM2);
2189
}
2190

    
2191
void OPPROTO op_ldstub_asi()                 /* XXX: should be atomically */
2192
{
2193
    target_ulong tmp;
2194

    
2195
    helper_ld_asi(PARAM1, 1, 0);
2196
    tmp = T1;
2197
    T1 = 0xff;
2198
    helper_st_asi(PARAM1, 1);
2199
    T1 = tmp;
2200
}
2201

    
2202
void OPPROTO op_swap_asi()                   /* XXX: should be atomically */
2203
{
2204
    target_ulong tmp1, tmp2;
2205

    
2206
    tmp1 = T1;
2207
    helper_ld_asi(PARAM1, 4, 0);
2208
    tmp2 = T1;
2209
    T1 = tmp1;
2210
    helper_st_asi(PARAM1, 4);
2211
    T1 = tmp2;
2212
}
2213
#endif
2214

    
2215
#ifdef TARGET_SPARC64
2216
// This function uses non-native bit order
2217
#define GET_FIELD(X, FROM, TO)                                  \
2218
    ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
2219

    
2220
// This function uses the order in the manuals, i.e. bit 0 is 2^0
2221
#define GET_FIELD_SP(X, FROM, TO)               \
2222
    GET_FIELD(X, 63 - (TO), 63 - (FROM))
2223

    
2224
void OPPROTO op_array8()
2225
{
2226
    T0 = (GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
2227
        (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
2228
        (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
2229
        (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
2230
        (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
2231
        (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12);
2232
}
2233

    
2234
void OPPROTO op_array16()
2235
{
2236
    T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
2237
          (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
2238
          (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
2239
          (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
2240
          (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
2241
          (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 1;
2242
}
2243

    
2244
void OPPROTO op_array32()
2245
{
2246
    T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
2247
          (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
2248
          (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
2249
          (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
2250
          (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
2251
          (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 2;
2252
}
2253

    
2254
void OPPROTO op_alignaddr()
2255
{
2256
    uint64_t tmp;
2257

    
2258
    tmp = T0 + T1;
2259
    env->gsr &= ~7ULL;
2260
    env->gsr |= tmp & 7ULL;
2261
    T0 = tmp & ~7ULL;
2262
}
2263

    
2264
void OPPROTO op_faligndata()
2265
{
2266
    uint64_t tmp;
2267

    
2268
    tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8);
2269
    tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
2270
    *((uint64_t *)&DT0) = tmp;
2271
}
2272

    
2273
void OPPROTO op_movl_FT0_0(void)
2274
{
2275
    *((uint32_t *)&FT0) = 0;
2276
}
2277

    
2278
void OPPROTO op_movl_DT0_0(void)
2279
{
2280
    *((uint64_t *)&DT0) = 0;
2281
}
2282

    
2283
void OPPROTO op_movl_FT0_1(void)
2284
{
2285
    *((uint32_t *)&FT0) = 0xffffffff;
2286
}
2287

    
2288
void OPPROTO op_movl_DT0_1(void)
2289
{
2290
    *((uint64_t *)&DT0) = 0xffffffffffffffffULL;
2291
}
2292

    
2293
void OPPROTO op_fnot(void)
2294
{
2295
    *(uint64_t *)&DT0 = ~*(uint64_t *)&DT1;
2296
}
2297

    
2298
void OPPROTO op_fnots(void)
2299
{
2300
    *(uint32_t *)&FT0 = ~*(uint32_t *)&FT1;
2301
}
2302

    
2303
void OPPROTO op_fnor(void)
2304
{
2305
    *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 | *(uint64_t *)&DT1);
2306
}
2307

    
2308
void OPPROTO op_fnors(void)
2309
{
2310
    *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 | *(uint32_t *)&FT1);
2311
}
2312

    
2313
void OPPROTO op_for(void)
2314
{
2315
    *(uint64_t *)&DT0 |= *(uint64_t *)&DT1;
2316
}
2317

    
2318
void OPPROTO op_fors(void)
2319
{
2320
    *(uint32_t *)&FT0 |= *(uint32_t *)&FT1;
2321
}
2322

    
2323
void OPPROTO op_fxor(void)
2324
{
2325
    *(uint64_t *)&DT0 ^= *(uint64_t *)&DT1;
2326
}
2327

    
2328
void OPPROTO op_fxors(void)
2329
{
2330
    *(uint32_t *)&FT0 ^= *(uint32_t *)&FT1;
2331
}
2332

    
2333
void OPPROTO op_fand(void)
2334
{
2335
    *(uint64_t *)&DT0 &= *(uint64_t *)&DT1;
2336
}
2337

    
2338
void OPPROTO op_fands(void)
2339
{
2340
    *(uint32_t *)&FT0 &= *(uint32_t *)&FT1;
2341
}
2342

    
2343
void OPPROTO op_fornot(void)
2344
{
2345
    *(uint64_t *)&DT0 = *(uint64_t *)&DT0 | ~*(uint64_t *)&DT1;
2346
}
2347

    
2348
void OPPROTO op_fornots(void)
2349
{
2350
    *(uint32_t *)&FT0 = *(uint32_t *)&FT0 | ~*(uint32_t *)&FT1;
2351
}
2352

    
2353
void OPPROTO op_fandnot(void)
2354
{
2355
    *(uint64_t *)&DT0 = *(uint64_t *)&DT0 & ~*(uint64_t *)&DT1;
2356
}
2357

    
2358
void OPPROTO op_fandnots(void)
2359
{
2360
    *(uint32_t *)&FT0 = *(uint32_t *)&FT0 & ~*(uint32_t *)&FT1;
2361
}
2362

    
2363
void OPPROTO op_fnand(void)
2364
{
2365
    *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 & *(uint64_t *)&DT1);
2366
}
2367

    
2368
void OPPROTO op_fnands(void)
2369
{
2370
    *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 & *(uint32_t *)&FT1);
2371
}
2372

    
2373
void OPPROTO op_fxnor(void)
2374
{
2375
    *(uint64_t *)&DT0 ^= ~*(uint64_t *)&DT1;
2376
}
2377

    
2378
void OPPROTO op_fxnors(void)
2379
{
2380
    *(uint32_t *)&FT0 ^= ~*(uint32_t *)&FT1;
2381
}
2382

    
2383
#ifdef WORDS_BIGENDIAN
2384
#define VIS_B64(n) b[7 - (n)]
2385
#define VIS_W64(n) w[3 - (n)]
2386
#define VIS_SW64(n) sw[3 - (n)]
2387
#define VIS_L64(n) l[1 - (n)]
2388
#define VIS_B32(n) b[3 - (n)]
2389
#define VIS_W32(n) w[1 - (n)]
2390
#else
2391
#define VIS_B64(n) b[n]
2392
#define VIS_W64(n) w[n]
2393
#define VIS_SW64(n) sw[n]
2394
#define VIS_L64(n) l[n]
2395
#define VIS_B32(n) b[n]
2396
#define VIS_W32(n) w[n]
2397
#endif
2398

    
2399
typedef union {
2400
    uint8_t b[8];
2401
    uint16_t w[4];
2402
    int16_t sw[4];
2403
    uint32_t l[2];
2404
    float64 d;
2405
} vis64;
2406

    
2407
typedef union {
2408
    uint8_t b[4];
2409
    uint16_t w[2];
2410
    uint32_t l;
2411
    float32 f;
2412
} vis32;
2413

    
2414
void OPPROTO op_fpmerge(void)
2415
{
2416
    vis64 s, d;
2417

    
2418
    s.d = DT0;
2419
    d.d = DT1;
2420

    
2421
    // Reverse calculation order to handle overlap
2422
    d.VIS_B64(7) = s.VIS_B64(3);
2423
    d.VIS_B64(6) = d.VIS_B64(3);
2424
    d.VIS_B64(5) = s.VIS_B64(2);
2425
    d.VIS_B64(4) = d.VIS_B64(2);
2426
    d.VIS_B64(3) = s.VIS_B64(1);
2427
    d.VIS_B64(2) = d.VIS_B64(1);
2428
    d.VIS_B64(1) = s.VIS_B64(0);
2429
    //d.VIS_B64(0) = d.VIS_B64(0);
2430

    
2431
    DT0 = d.d;
2432
}
2433

    
2434
void OPPROTO op_fmul8x16(void)
2435
{
2436
    vis64 s, d;
2437
    uint32_t tmp;
2438

    
2439
    s.d = DT0;
2440
    d.d = DT1;
2441

    
2442
#define PMUL(r)                                                 \
2443
    tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r);       \
2444
    if ((tmp & 0xff) > 0x7f)                                    \
2445
        tmp += 0x100;                                           \
2446
    d.VIS_W64(r) = tmp >> 8;
2447

    
2448
    PMUL(0);
2449
    PMUL(1);
2450
    PMUL(2);
2451
    PMUL(3);
2452
#undef PMUL
2453

    
2454
    DT0 = d.d;
2455
}
2456

    
2457
void OPPROTO op_fmul8x16al(void)
2458
{
2459
    vis64 s, d;
2460
    uint32_t tmp;
2461

    
2462
    s.d = DT0;
2463
    d.d = DT1;
2464

    
2465
#define PMUL(r)                                                 \
2466
    tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r);       \
2467
    if ((tmp & 0xff) > 0x7f)                                    \
2468
        tmp += 0x100;                                           \
2469
    d.VIS_W64(r) = tmp >> 8;
2470

    
2471
    PMUL(0);
2472
    PMUL(1);
2473
    PMUL(2);
2474
    PMUL(3);
2475
#undef PMUL
2476

    
2477
    DT0 = d.d;
2478
}
2479

    
2480
void OPPROTO op_fmul8x16au(void)
2481
{
2482
    vis64 s, d;
2483
    uint32_t tmp;
2484

    
2485
    s.d = DT0;
2486
    d.d = DT1;
2487

    
2488
#define PMUL(r)                                                 \
2489
    tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r);       \
2490
    if ((tmp & 0xff) > 0x7f)                                    \
2491
        tmp += 0x100;                                           \
2492
    d.VIS_W64(r) = tmp >> 8;
2493

    
2494
    PMUL(0);
2495
    PMUL(1);
2496
    PMUL(2);
2497
    PMUL(3);
2498
#undef PMUL
2499

    
2500
    DT0 = d.d;
2501
}
2502

    
2503
void OPPROTO op_fmul8sux16(void)
2504
{
2505
    vis64 s, d;
2506
    uint32_t tmp;
2507

    
2508
    s.d = DT0;
2509
    d.d = DT1;
2510

    
2511
#define PMUL(r)                                                         \
2512
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
2513
    if ((tmp & 0xff) > 0x7f)                                            \
2514
        tmp += 0x100;                                                   \
2515
    d.VIS_W64(r) = tmp >> 8;
2516

    
2517
    PMUL(0);
2518
    PMUL(1);
2519
    PMUL(2);
2520
    PMUL(3);
2521
#undef PMUL
2522

    
2523
    DT0 = d.d;
2524
}
2525

    
2526
void OPPROTO op_fmul8ulx16(void)
2527
{
2528
    vis64 s, d;
2529
    uint32_t tmp;
2530

    
2531
    s.d = DT0;
2532
    d.d = DT1;
2533

    
2534
#define PMUL(r)                                                         \
2535
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
2536
    if ((tmp & 0xff) > 0x7f)                                            \
2537
        tmp += 0x100;                                                   \
2538
    d.VIS_W64(r) = tmp >> 8;
2539

    
2540
    PMUL(0);
2541
    PMUL(1);
2542
    PMUL(2);
2543
    PMUL(3);
2544
#undef PMUL
2545

    
2546
    DT0 = d.d;
2547
}
2548

    
2549
void OPPROTO op_fmuld8sux16(void)
2550
{
2551
    vis64 s, d;
2552
    uint32_t tmp;
2553

    
2554
    s.d = DT0;
2555
    d.d = DT1;
2556

    
2557
#define PMUL(r)                                                         \
2558
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
2559
    if ((tmp & 0xff) > 0x7f)                                            \
2560
        tmp += 0x100;                                                   \
2561
    d.VIS_L64(r) = tmp;
2562

    
2563
    // Reverse calculation order to handle overlap
2564
    PMUL(1);
2565
    PMUL(0);
2566
#undef PMUL
2567

    
2568
    DT0 = d.d;
2569
}
2570

    
2571
void OPPROTO op_fmuld8ulx16(void)
2572
{
2573
    vis64 s, d;
2574
    uint32_t tmp;
2575

    
2576
    s.d = DT0;
2577
    d.d = DT1;
2578

    
2579
#define PMUL(r)                                                         \
2580
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
2581
    if ((tmp & 0xff) > 0x7f)                                            \
2582
        tmp += 0x100;                                                   \
2583
    d.VIS_L64(r) = tmp;
2584

    
2585
    // Reverse calculation order to handle overlap
2586
    PMUL(1);
2587
    PMUL(0);
2588
#undef PMUL
2589

    
2590
    DT0 = d.d;
2591
}
2592

    
2593
void OPPROTO op_fexpand(void)
2594
{
2595
    vis32 s;
2596
    vis64 d;
2597

    
2598
    s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff);
2599
    d.d = DT1;
2600
    d.VIS_L64(0) = s.VIS_W32(0) << 4;
2601
    d.VIS_L64(1) = s.VIS_W32(1) << 4;
2602
    d.VIS_L64(2) = s.VIS_W32(2) << 4;
2603
    d.VIS_L64(3) = s.VIS_W32(3) << 4;
2604

    
2605
    DT0 = d.d;
2606
}
2607

    
2608
#define VIS_OP(name, F)                                 \
2609
    void OPPROTO name##16(void)                         \
2610
    {                                                   \
2611
        vis64 s, d;                                     \
2612
                                                        \
2613
        s.d = DT0;                                      \
2614
        d.d = DT1;                                      \
2615
                                                        \
2616
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0));   \
2617
        d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1));   \
2618
        d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2));   \
2619
        d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3));   \
2620
                                                        \
2621
        DT0 = d.d;                                      \
2622
    }                                                   \
2623
                                                        \
2624
    void OPPROTO name##16s(void)                        \
2625
    {                                                   \
2626
        vis32 s, d;                                     \
2627
                                                        \
2628
        s.f = FT0;                                      \
2629
        d.f = FT1;                                      \
2630
                                                        \
2631
        d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0));   \
2632
        d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1));   \
2633
                                                        \
2634
        FT0 = d.f;                                      \
2635
    }                                                   \
2636
                                                        \
2637
    void OPPROTO name##32(void)                         \
2638
    {                                                   \
2639
        vis64 s, d;                                     \
2640
                                                        \
2641
        s.d = DT0;                                      \
2642
        d.d = DT1;                                      \
2643
                                                        \
2644
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0));   \
2645
        d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1));   \
2646
                                                        \
2647
        DT0 = d.d;                                      \
2648
    }                                                   \
2649
                                                        \
2650
    void OPPROTO name##32s(void)                        \
2651
    {                                                   \
2652
        vis32 s, d;                                     \
2653
                                                        \
2654
        s.f = FT0;                                      \
2655
        d.f = FT1;                                      \
2656
                                                        \
2657
        d.l = F(d.l, s.l);                              \
2658
                                                        \
2659
        FT0 = d.f;                                      \
2660
    }
2661

    
2662
#define FADD(a, b) ((a) + (b))
2663
#define FSUB(a, b) ((a) - (b))
2664
VIS_OP(op_fpadd, FADD)
2665
VIS_OP(op_fpsub, FSUB)
2666

    
2667
#define VIS_CMPOP(name, F)                                        \
2668
    void OPPROTO name##16(void)                                   \
2669
    {                                                             \
2670
        vis64 s, d;                                               \
2671
                                                                  \
2672
        s.d = DT0;                                                \
2673
        d.d = DT1;                                                \
2674
                                                                  \
2675
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0;       \
2676
        d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0;      \
2677
        d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0;      \
2678
        d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0;      \
2679
                                                                  \
2680
        DT0 = d.d;                                                \
2681
    }                                                             \
2682
                                                                  \
2683
    void OPPROTO name##32(void)                                   \
2684
    {                                                             \
2685
        vis64 s, d;                                               \
2686
                                                                  \
2687
        s.d = DT0;                                                \
2688
        d.d = DT1;                                                \
2689
                                                                  \
2690
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0;       \
2691
        d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0;      \
2692
                                                                  \
2693
        DT0 = d.d;                                                \
2694
    }
2695

    
2696
#define FCMPGT(a, b) ((a) > (b))
2697
#define FCMPEQ(a, b) ((a) == (b))
2698
#define FCMPLE(a, b) ((a) <= (b))
2699
#define FCMPNE(a, b) ((a) != (b))
2700

    
2701
VIS_CMPOP(op_fcmpgt, FCMPGT)
2702
VIS_CMPOP(op_fcmpeq, FCMPEQ)
2703
VIS_CMPOP(op_fcmple, FCMPLE)
2704
VIS_CMPOP(op_fcmpne, FCMPNE)
2705

    
2706
#endif
2707

    
2708
#define CHECK_ALIGN_OP(align)                           \
2709
    void OPPROTO op_check_align_T0_ ## align (void)     \
2710
    {                                                   \
2711
        if (T0 & align)                                 \
2712
            raise_exception(TT_UNALIGNED);              \
2713
        FORCE_RET();                                    \
2714
    }
2715

    
2716
CHECK_ALIGN_OP(1)
2717
CHECK_ALIGN_OP(3)
2718
CHECK_ALIGN_OP(7)