Statistics
| Branch: | Revision:

root / target-sparc / op.c @ 3b46e624

History | View | Annotate | Download (48 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

    
526
    src1 = T0;
527
    T0 += T1;
528

    
529
#ifdef TARGET_SPARC64
530
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
531
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
532
        raise_exception(TT_TOVF);
533
#else
534
    if ((src1 & 0x03) || (T1 & 0x03))
535
        raise_exception(TT_TOVF);
536
#endif
537

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

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

    
565
void OPPROTO op_sub_T1_T0(void)
566
{
567
    T0 -= T1;
568
}
569

    
570
void OPPROTO op_sub_T1_T0_cc(void)
571
{
572
    target_ulong src1;
573

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

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

    
610
void OPPROTO op_subx_T1_T0(void)
611
{
612
    T0 -= T1 + FLAG_SET(PSR_CARRY);
613
}
614

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

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

    
675
void OPPROTO op_tsub_T1_T0_cc(void)
676
{
677
    target_ulong src1;
678

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

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

    
719
void OPPROTO op_tsub_T1_T0_ccTV(void)
720
{
721
    target_ulong src1;
722

    
723
    if ((T0 & 0x03) || (T1 & 0x03))
724
        raise_exception(TT_TOVF);
725

    
726
    src1 = T0;
727
    T0 -= T1;
728

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

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

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

    
765
void OPPROTO op_and_T1_T0(void)
766
{
767
    T0 &= T1;
768
}
769

    
770
void OPPROTO op_or_T1_T0(void)
771
{
772
    T0 |= T1;
773
}
774

    
775
void OPPROTO op_xor_T1_T0(void)
776
{
777
    T0 ^= T1;
778
}
779

    
780
void OPPROTO op_andn_T1_T0(void)
781
{
782
    T0 &= ~T1;
783
}
784

    
785
void OPPROTO op_orn_T1_T0(void)
786
{
787
    T0 |= ~T1;
788
}
789

    
790
void OPPROTO op_xnor_T1_T0(void)
791
{
792
    T0 ^= ~T1;
793
}
794

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

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

    
819
void OPPROTO op_mulscc_T1_T0(void)
820
{
821
    unsigned int b1, N, V, b2;
822
    target_ulong src1;
823

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

    
847
void OPPROTO op_udiv_T1_T0(void)
848
{
849
    uint64_t x0;
850
    uint32_t x1;
851

    
852
    x0 = T0 | ((uint64_t) (env->y) << 32);
853
    x1 = T1;
854

    
855
    if (x1 == 0) {
856
        raise_exception(TT_DIV_ZERO);
857
    }
858

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

    
870
void OPPROTO op_sdiv_T1_T0(void)
871
{
872
    int64_t x0;
873
    int32_t x1;
874

    
875
    x0 = T0 | ((int64_t) (env->y) << 32);
876
    x1 = T1;
877

    
878
    if (x1 == 0) {
879
        raise_exception(TT_DIV_ZERO);
880
    }
881

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

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

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

    
920
#ifdef TARGET_SPARC64
921
void OPPROTO op_mulx_T1_T0(void)
922
{
923
    T0 *= T1;
924
    FORCE_RET();
925
}
926

    
927
void OPPROTO op_udivx_T1_T0(void)
928
{
929
    if (T1 == 0) {
930
        raise_exception(TT_DIV_ZERO);
931
    }
932
    T0 /= T1;
933
    FORCE_RET();
934
}
935

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

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

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

    
972
void OPPROTO op_sll(void)
973
{
974
    T0 <<= (T1 & 0x1f);
975
}
976

    
977
#ifdef TARGET_SPARC64
978
void OPPROTO op_sllx(void)
979
{
980
    T0 <<= (T1 & 0x3f);
981
}
982

    
983
void OPPROTO op_srl(void)
984
{
985
    T0 = (T0 & 0xffffffff) >> (T1 & 0x1f);
986
}
987

    
988
void OPPROTO op_srlx(void)
989
{
990
    T0 >>= (T1 & 0x3f);
991
}
992

    
993
void OPPROTO op_sra(void)
994
{
995
    T0 = ((int32_t) (T0 & 0xffffffff)) >> (T1 & 0x1f);
996
}
997

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

    
1008
void OPPROTO op_sra(void)
1009
{
1010
    T0 = ((int32_t) T0) >> (T1 & 0x1f);
1011
}
1012
#endif
1013

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

    
1021
#define MEMSUFFIX _kernel
1022
#include "op_mem.h"
1023
#endif
1024

    
1025
void OPPROTO op_ldfsr(void)
1026
{
1027
    PUT_FSR32(env, *((uint32_t *) &FT0));
1028
    helper_ldfsr();
1029
}
1030

    
1031
void OPPROTO op_stfsr(void)
1032
{
1033
    *((uint32_t *) &FT0) = GET_FSR32(env);
1034
}
1035

    
1036
#ifndef TARGET_SPARC64
1037
void OPPROTO op_rdpsr(void)
1038
{
1039
    do_rdpsr();
1040
}
1041

    
1042
void OPPROTO op_wrpsr(void)
1043
{
1044
    do_wrpsr();
1045
    FORCE_RET();
1046
}
1047

    
1048
void OPPROTO op_wrwim(void)
1049
{
1050
#if NWINDOWS == 32
1051
    env->wim = T0;
1052
#else
1053
    env->wim = T0 & ((1 << NWINDOWS) - 1);
1054
#endif
1055
}
1056

    
1057
void OPPROTO op_rett(void)
1058
{
1059
    helper_rett();
1060
    FORCE_RET();
1061
}
1062

    
1063
/* XXX: use another pointer for %iN registers to avoid slow wrapping
1064
   handling ? */
1065
void OPPROTO op_save(void)
1066
{
1067
    uint32_t cwp;
1068
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
1069
    if (env->wim & (1 << cwp)) {
1070
        raise_exception(TT_WIN_OVF);
1071
    }
1072
    set_cwp(cwp);
1073
    FORCE_RET();
1074
}
1075

    
1076
void OPPROTO op_restore(void)
1077
{
1078
    uint32_t cwp;
1079
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
1080
    if (env->wim & (1 << cwp)) {
1081
        raise_exception(TT_WIN_UNF);
1082
    }
1083
    set_cwp(cwp);
1084
    FORCE_RET();
1085
}
1086
#else
1087
void OPPROTO op_rdccr(void)
1088
{
1089
    T0 = GET_CCR(env);
1090
}
1091

    
1092
void OPPROTO op_wrccr(void)
1093
{
1094
    PUT_CCR(env, T0);
1095
}
1096

    
1097
void OPPROTO op_rdtick(void)
1098
{
1099
    T0 = do_tick_get_count(env->tick);
1100
}
1101

    
1102
void OPPROTO op_wrtick(void)
1103
{
1104
    do_tick_set_count(env->tick, T0);
1105
}
1106

    
1107
void OPPROTO op_wrtick_cmpr(void)
1108
{
1109
    do_tick_set_limit(env->tick, T0);
1110
}
1111

    
1112
void OPPROTO op_rdstick(void)
1113
{
1114
    T0 = do_tick_get_count(env->stick);
1115
}
1116

    
1117
void OPPROTO op_wrstick(void)
1118
{
1119
    do_tick_set_count(env->stick, T0);
1120
    do_tick_set_count(env->hstick, T0);
1121
}
1122

    
1123
void OPPROTO op_wrstick_cmpr(void)
1124
{
1125
    do_tick_set_limit(env->stick, T0);
1126
}
1127

    
1128
void OPPROTO op_wrhstick_cmpr(void)
1129
{
1130
    do_tick_set_limit(env->hstick, T0);
1131
}
1132

    
1133
void OPPROTO op_rdtpc(void)
1134
{
1135
    T0 = env->tpc[env->tl];
1136
}
1137

    
1138
void OPPROTO op_wrtpc(void)
1139
{
1140
    env->tpc[env->tl] = T0;
1141
}
1142

    
1143
void OPPROTO op_rdtnpc(void)
1144
{
1145
    T0 = env->tnpc[env->tl];
1146
}
1147

    
1148
void OPPROTO op_wrtnpc(void)
1149
{
1150
    env->tnpc[env->tl] = T0;
1151
}
1152

    
1153
void OPPROTO op_rdtstate(void)
1154
{
1155
    T0 = env->tstate[env->tl];
1156
}
1157

    
1158
void OPPROTO op_wrtstate(void)
1159
{
1160
    env->tstate[env->tl] = T0;
1161
}
1162

    
1163
void OPPROTO op_rdtt(void)
1164
{
1165
    T0 = env->tt[env->tl];
1166
}
1167

    
1168
void OPPROTO op_wrtt(void)
1169
{
1170
    env->tt[env->tl] = T0;
1171
}
1172

    
1173
void OPPROTO op_rdpstate(void)
1174
{
1175
    T0 = env->pstate;
1176
}
1177

    
1178
void OPPROTO op_wrpstate(void)
1179
{
1180
    do_wrpstate();
1181
}
1182

    
1183
// CWP handling is reversed in V9, but we still use the V8 register
1184
// order.
1185
void OPPROTO op_rdcwp(void)
1186
{
1187
    T0 = GET_CWP64(env);
1188
}
1189

    
1190
void OPPROTO op_wrcwp(void)
1191
{
1192
    PUT_CWP64(env, T0);
1193
}
1194

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

    
1218
void OPPROTO op_restore(void)
1219
{
1220
    uint32_t cwp;
1221
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
1222
    if (env->canrestore == 0) {
1223
        raise_exception(TT_FILL | (env->otherwin != 0 ?
1224
                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1225
                                   ((env->wstate & 0x7) << 2)));
1226
    } else {
1227
        env->cansave++;
1228
        env->canrestore--;
1229
        set_cwp(cwp);
1230
    }
1231
    FORCE_RET();
1232
}
1233
#endif
1234

    
1235
void OPPROTO op_exception(void)
1236
{
1237
    env->exception_index = PARAM1;
1238
    cpu_loop_exit();
1239
}
1240

    
1241
void OPPROTO op_trap_T0(void)
1242
{
1243
    env->exception_index = TT_TRAP + (T0 & 0x7f);
1244
    cpu_loop_exit();
1245
}
1246

    
1247
void OPPROTO op_trapcc_T0(void)
1248
{
1249
    if (T2) {
1250
        env->exception_index = TT_TRAP + (T0 & 0x7f);
1251
        cpu_loop_exit();
1252
    }
1253
    FORCE_RET();
1254
}
1255

    
1256
void OPPROTO op_fpexception_im(void)
1257
{
1258
    env->exception_index = TT_FP_EXCP;
1259
    env->fsr &= ~FSR_FTT_MASK;
1260
    env->fsr |= PARAM1;
1261
    cpu_loop_exit();
1262
    FORCE_RET();
1263
}
1264

    
1265
void OPPROTO op_debug(void)
1266
{
1267
    helper_debug();
1268
}
1269

    
1270
void OPPROTO op_exit_tb(void)
1271
{
1272
    EXIT_TB();
1273
}
1274

    
1275
void OPPROTO op_eval_ba(void)
1276
{
1277
    T2 = 1;
1278
}
1279

    
1280
void OPPROTO op_eval_be(void)
1281
{
1282
    T2 = FLAG_SET(PSR_ZERO);
1283
}
1284

    
1285
void OPPROTO op_eval_ble(void)
1286
{
1287
    target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1288

    
1289
    T2 = Z | (N ^ V);
1290
}
1291

    
1292
void OPPROTO op_eval_bl(void)
1293
{
1294
    target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1295

    
1296
    T2 = N ^ V;
1297
}
1298

    
1299
void OPPROTO op_eval_bleu(void)
1300
{
1301
    target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1302

    
1303
    T2 = C | Z;
1304
}
1305

    
1306
void OPPROTO op_eval_bcs(void)
1307
{
1308
    T2 = FLAG_SET(PSR_CARRY);
1309
}
1310

    
1311
void OPPROTO op_eval_bvs(void)
1312
{
1313
    T2 = FLAG_SET(PSR_OVF);
1314
}
1315

    
1316
void OPPROTO op_eval_bn(void)
1317
{
1318
    T2 = 0;
1319
}
1320

    
1321
void OPPROTO op_eval_bneg(void)
1322
{
1323
    T2 = FLAG_SET(PSR_NEG);
1324
}
1325

    
1326
void OPPROTO op_eval_bne(void)
1327
{
1328
    T2 = !FLAG_SET(PSR_ZERO);
1329
}
1330

    
1331
void OPPROTO op_eval_bg(void)
1332
{
1333
    target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1334

    
1335
    T2 = !(Z | (N ^ V));
1336
}
1337

    
1338
void OPPROTO op_eval_bge(void)
1339
{
1340
    target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1341

    
1342
    T2 = !(N ^ V);
1343
}
1344

    
1345
void OPPROTO op_eval_bgu(void)
1346
{
1347
    target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1348

    
1349
    T2 = !(C | Z);
1350
}
1351

    
1352
void OPPROTO op_eval_bcc(void)
1353
{
1354
    T2 = !FLAG_SET(PSR_CARRY);
1355
}
1356

    
1357
void OPPROTO op_eval_bpos(void)
1358
{
1359
    T2 = !FLAG_SET(PSR_NEG);
1360
}
1361

    
1362
void OPPROTO op_eval_bvc(void)
1363
{
1364
    T2 = !FLAG_SET(PSR_OVF);
1365
}
1366

    
1367
#ifdef TARGET_SPARC64
1368
void OPPROTO op_eval_xbe(void)
1369
{
1370
    T2 = XFLAG_SET(PSR_ZERO);
1371
}
1372

    
1373
void OPPROTO op_eval_xble(void)
1374
{
1375
    target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1376

    
1377
    T2 = Z | (N ^ V);
1378
}
1379

    
1380
void OPPROTO op_eval_xbl(void)
1381
{
1382
    target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1383

    
1384
    T2 = N ^ V;
1385
}
1386

    
1387
void OPPROTO op_eval_xbleu(void)
1388
{
1389
    target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1390

    
1391
    T2 = C | Z;
1392
}
1393

    
1394
void OPPROTO op_eval_xbcs(void)
1395
{
1396
    T2 = XFLAG_SET(PSR_CARRY);
1397
}
1398

    
1399
void OPPROTO op_eval_xbvs(void)
1400
{
1401
    T2 = XFLAG_SET(PSR_OVF);
1402
}
1403

    
1404
void OPPROTO op_eval_xbneg(void)
1405
{
1406
    T2 = XFLAG_SET(PSR_NEG);
1407
}
1408

    
1409
void OPPROTO op_eval_xbne(void)
1410
{
1411
    T2 = !XFLAG_SET(PSR_ZERO);
1412
}
1413

    
1414
void OPPROTO op_eval_xbg(void)
1415
{
1416
    target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1417

    
1418
    T2 = !(Z | (N ^ V));
1419
}
1420

    
1421
void OPPROTO op_eval_xbge(void)
1422
{
1423
    target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1424

    
1425
    T2 = !(N ^ V);
1426
}
1427

    
1428
void OPPROTO op_eval_xbgu(void)
1429
{
1430
    target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1431

    
1432
    T2 = !(C | Z);
1433
}
1434

    
1435
void OPPROTO op_eval_xbcc(void)
1436
{
1437
    T2 = !XFLAG_SET(PSR_CARRY);
1438
}
1439

    
1440
void OPPROTO op_eval_xbpos(void)
1441
{
1442
    T2 = !XFLAG_SET(PSR_NEG);
1443
}
1444

    
1445
void OPPROTO op_eval_xbvc(void)
1446
{
1447
    T2 = !XFLAG_SET(PSR_OVF);
1448
}
1449
#endif
1450

    
1451
#define FCC
1452
#define FFLAG_SET(x) (env->fsr & x? 1: 0)
1453
#include "fbranch_template.h"
1454

    
1455
#ifdef TARGET_SPARC64
1456
#define FCC _fcc1
1457
#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
1458
#include "fbranch_template.h"
1459
#define FCC _fcc2
1460
#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
1461
#include "fbranch_template.h"
1462
#define FCC _fcc3
1463
#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
1464
#include "fbranch_template.h"
1465
#endif
1466

    
1467
#ifdef TARGET_SPARC64
1468
void OPPROTO op_eval_brz(void)
1469
{
1470
    T2 = (T0 == 0);
1471
}
1472

    
1473
void OPPROTO op_eval_brnz(void)
1474
{
1475
    T2 = (T0 != 0);
1476
}
1477

    
1478
void OPPROTO op_eval_brlz(void)
1479
{
1480
    T2 = ((int64_t)T0 < 0);
1481
}
1482

    
1483
void OPPROTO op_eval_brlez(void)
1484
{
1485
    T2 = ((int64_t)T0 <= 0);
1486
}
1487

    
1488
void OPPROTO op_eval_brgz(void)
1489
{
1490
    T2 = ((int64_t)T0 > 0);
1491
}
1492

    
1493
void OPPROTO op_eval_brgez(void)
1494
{
1495
    T2 = ((int64_t)T0 >= 0);
1496
}
1497

    
1498
void OPPROTO op_jmp_im64(void)
1499
{
1500
    env->pc = PARAMQ1;
1501
}
1502

    
1503
void OPPROTO op_movq_npc_im64(void)
1504
{
1505
    env->npc = PARAMQ1;
1506
}
1507
#endif
1508

    
1509
void OPPROTO op_jmp_im(void)
1510
{
1511
    env->pc = (uint32_t)PARAM1;
1512
}
1513

    
1514
void OPPROTO op_movl_npc_im(void)
1515
{
1516
    env->npc = (uint32_t)PARAM1;
1517
}
1518

    
1519
void OPPROTO op_movl_npc_T0(void)
1520
{
1521
    env->npc = T0;
1522
}
1523

    
1524
void OPPROTO op_mov_pc_npc(void)
1525
{
1526
    env->pc = env->npc;
1527
}
1528

    
1529
void OPPROTO op_next_insn(void)
1530
{
1531
    env->pc = env->npc;
1532
    env->npc = env->npc + 4;
1533
}
1534

    
1535
void OPPROTO op_goto_tb0(void)
1536
{
1537
    GOTO_TB(op_goto_tb0, PARAM1, 0);
1538
}
1539

    
1540
void OPPROTO op_goto_tb1(void)
1541
{
1542
    GOTO_TB(op_goto_tb1, PARAM1, 1);
1543
}
1544

    
1545
void OPPROTO op_jmp_label(void)
1546
{
1547
    GOTO_LABEL_PARAM(1);
1548
}
1549

    
1550
void OPPROTO op_jnz_T2_label(void)
1551
{
1552
    if (T2)
1553
        GOTO_LABEL_PARAM(1);
1554
    FORCE_RET();
1555
}
1556

    
1557
void OPPROTO op_jz_T2_label(void)
1558
{
1559
    if (!T2)
1560
        GOTO_LABEL_PARAM(1);
1561
    FORCE_RET();
1562
}
1563

    
1564
void OPPROTO op_flush_T0(void)
1565
{
1566
    helper_flush(T0);
1567
}
1568

    
1569
void OPPROTO op_clear_ieee_excp_and_FTT(void)
1570
{
1571
    env->fsr &= ~(FSR_FTT_MASK | FSR_CEXC_MASK);;
1572
}
1573

    
1574
#define F_OP(name, p) void OPPROTO op_f##name##p(void)
1575

    
1576
#define F_BINOP(name)                                           \
1577
    F_OP(name, s)                                               \
1578
    {                                                           \
1579
        set_float_exception_flags(0, &env->fp_status);                \
1580
        FT0 = float32_ ## name (FT0, FT1, &env->fp_status);     \
1581
        check_ieee_exceptions();                                \
1582
    }                                                           \
1583
    F_OP(name, d)                                               \
1584
    {                                                           \
1585
        set_float_exception_flags(0, &env->fp_status);                \
1586
        DT0 = float64_ ## name (DT0, DT1, &env->fp_status);     \
1587
        check_ieee_exceptions();                                \
1588
    }
1589

    
1590
F_BINOP(add);
1591
F_BINOP(sub);
1592
F_BINOP(mul);
1593
F_BINOP(div);
1594
#undef F_BINOP
1595

    
1596
void OPPROTO op_fsmuld(void)
1597
{
1598
    set_float_exception_flags(0, &env->fp_status);
1599
    DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status),
1600
                      float32_to_float64(FT1, &env->fp_status),
1601
                      &env->fp_status);
1602
    check_ieee_exceptions();
1603
}
1604

    
1605
#define F_HELPER(name)    \
1606
    F_OP(name, s)         \
1607
    {                     \
1608
        do_f##name##s();  \
1609
    }                     \
1610
    F_OP(name, d)         \
1611
    {                     \
1612
        do_f##name##d();  \
1613
    }
1614

    
1615
F_HELPER(sqrt);
1616

    
1617
F_OP(neg, s)
1618
{
1619
    FT0 = float32_chs(FT1);
1620
}
1621

    
1622
F_OP(abs, s)
1623
{
1624
    do_fabss();
1625
}
1626

    
1627
F_HELPER(cmp);
1628
F_HELPER(cmpe);
1629

    
1630
#ifdef TARGET_SPARC64
1631
F_OP(neg, d)
1632
{
1633
    DT0 = float64_chs(DT1);
1634
}
1635

    
1636
F_OP(abs, d)
1637
{
1638
    do_fabsd();
1639
}
1640

    
1641
void OPPROTO op_fcmps_fcc1(void)
1642
{
1643
    do_fcmps_fcc1();
1644
}
1645

    
1646
void OPPROTO op_fcmpd_fcc1(void)
1647
{
1648
    do_fcmpd_fcc1();
1649
}
1650

    
1651
void OPPROTO op_fcmps_fcc2(void)
1652
{
1653
    do_fcmps_fcc2();
1654
}
1655

    
1656
void OPPROTO op_fcmpd_fcc2(void)
1657
{
1658
    do_fcmpd_fcc2();
1659
}
1660

    
1661
void OPPROTO op_fcmps_fcc3(void)
1662
{
1663
    do_fcmps_fcc3();
1664
}
1665

    
1666
void OPPROTO op_fcmpd_fcc3(void)
1667
{
1668
    do_fcmpd_fcc3();
1669
}
1670

    
1671
void OPPROTO op_fcmpes_fcc1(void)
1672
{
1673
    do_fcmpes_fcc1();
1674
}
1675

    
1676
void OPPROTO op_fcmped_fcc1(void)
1677
{
1678
    do_fcmped_fcc1();
1679
}
1680

    
1681
void OPPROTO op_fcmpes_fcc2(void)
1682
{
1683
    do_fcmpes_fcc2();
1684
}
1685

    
1686
void OPPROTO op_fcmped_fcc2(void)
1687
{
1688
    do_fcmped_fcc2();
1689
}
1690

    
1691
void OPPROTO op_fcmpes_fcc3(void)
1692
{
1693
    do_fcmpes_fcc3();
1694
}
1695

    
1696
void OPPROTO op_fcmped_fcc3(void)
1697
{
1698
    do_fcmped_fcc3();
1699
}
1700

    
1701
#endif
1702

    
1703
/* Integer to float conversion.  */
1704
#ifdef USE_INT_TO_FLOAT_HELPERS
1705
F_HELPER(ito);
1706
#else
1707
F_OP(ito, s)
1708
{
1709
    set_float_exception_flags(0, &env->fp_status);
1710
    FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
1711
    check_ieee_exceptions();
1712
}
1713

    
1714
F_OP(ito, d)
1715
{
1716
    set_float_exception_flags(0, &env->fp_status);
1717
    DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
1718
    check_ieee_exceptions();
1719
}
1720

    
1721
#ifdef TARGET_SPARC64
1722
F_OP(xto, s)
1723
{
1724
    set_float_exception_flags(0, &env->fp_status);
1725
    FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
1726
    check_ieee_exceptions();
1727
}
1728

    
1729
F_OP(xto, d)
1730
{
1731
    set_float_exception_flags(0, &env->fp_status);
1732
    DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
1733
    check_ieee_exceptions();
1734
}
1735
#endif
1736
#endif
1737
#undef F_HELPER
1738

    
1739
/* floating point conversion */
1740
void OPPROTO op_fdtos(void)
1741
{
1742
    set_float_exception_flags(0, &env->fp_status);
1743
    FT0 = float64_to_float32(DT1, &env->fp_status);
1744
    check_ieee_exceptions();
1745
}
1746

    
1747
void OPPROTO op_fstod(void)
1748
{
1749
    set_float_exception_flags(0, &env->fp_status);
1750
    DT0 = float32_to_float64(FT1, &env->fp_status);
1751
    check_ieee_exceptions();
1752
}
1753

    
1754
/* Float to integer conversion.  */
1755
void OPPROTO op_fstoi(void)
1756
{
1757
    set_float_exception_flags(0, &env->fp_status);
1758
    *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status);
1759
    check_ieee_exceptions();
1760
}
1761

    
1762
void OPPROTO op_fdtoi(void)
1763
{
1764
    set_float_exception_flags(0, &env->fp_status);
1765
    *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
1766
    check_ieee_exceptions();
1767
}
1768

    
1769
#ifdef TARGET_SPARC64
1770
void OPPROTO op_fstox(void)
1771
{
1772
    set_float_exception_flags(0, &env->fp_status);
1773
    *((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status);
1774
    check_ieee_exceptions();
1775
}
1776

    
1777
void OPPROTO op_fdtox(void)
1778
{
1779
    set_float_exception_flags(0, &env->fp_status);
1780
    *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
1781
    check_ieee_exceptions();
1782
}
1783

    
1784
void OPPROTO op_fmovs_cc(void)
1785
{
1786
    if (T2)
1787
        FT0 = FT1;
1788
}
1789

    
1790
void OPPROTO op_fmovd_cc(void)
1791
{
1792
    if (T2)
1793
        DT0 = DT1;
1794
}
1795

    
1796
void OPPROTO op_mov_cc(void)
1797
{
1798
    if (T2)
1799
        T0 = T1;
1800
}
1801

    
1802
void OPPROTO op_flushw(void)
1803
{
1804
    if (env->cansave != NWINDOWS - 2) {
1805
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
1806
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1807
                                    ((env->wstate & 0x7) << 2)));
1808
    }
1809
}
1810

    
1811
void OPPROTO op_saved(void)
1812
{
1813
    env->cansave++;
1814
    if (env->otherwin == 0)
1815
        env->canrestore--;
1816
    else
1817
        env->otherwin--;
1818
    FORCE_RET();
1819
}
1820

    
1821
void OPPROTO op_restored(void)
1822
{
1823
    env->canrestore++;
1824
    if (env->cleanwin < NWINDOWS - 1)
1825
        env->cleanwin++;
1826
    if (env->otherwin == 0)
1827
        env->cansave--;
1828
    else
1829
        env->otherwin--;
1830
    FORCE_RET();
1831
}
1832

    
1833
void OPPROTO op_popc(void)
1834
{
1835
    do_popc();
1836
}
1837

    
1838
void OPPROTO op_done(void)
1839
{
1840
    do_done();
1841
}
1842

    
1843
void OPPROTO op_retry(void)
1844
{
1845
    do_retry();
1846
}
1847

    
1848
void OPPROTO op_sir(void)
1849
{
1850
    T0 = 0;  // XXX
1851
}
1852

    
1853
void OPPROTO op_ld_asi_reg()
1854
{
1855
    T0 += PARAM1;
1856
    helper_ld_asi(env->asi, PARAM2, PARAM3);
1857
}
1858

    
1859
void OPPROTO op_st_asi_reg()
1860
{
1861
    T0 += PARAM1;
1862
    helper_st_asi(env->asi, PARAM2, PARAM3);
1863
}
1864
#endif
1865

    
1866
void OPPROTO op_ld_asi()
1867
{
1868
    helper_ld_asi(PARAM1, PARAM2, PARAM3);
1869
}
1870

    
1871
void OPPROTO op_st_asi()
1872
{
1873
    helper_st_asi(PARAM1, PARAM2, PARAM3);
1874
}
1875

    
1876
#ifdef TARGET_SPARC64
1877
// This function uses non-native bit order
1878
#define GET_FIELD(X, FROM, TO)                                  \
1879
    ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
1880

    
1881
// This function uses the order in the manuals, i.e. bit 0 is 2^0
1882
#define GET_FIELD_SP(X, FROM, TO)               \
1883
    GET_FIELD(X, 63 - (TO), 63 - (FROM))
1884

    
1885
void OPPROTO op_array8()
1886
{
1887
    T0 = (GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1888
        (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1889
        (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1890
        (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1891
        (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1892
        (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12);
1893
}
1894

    
1895
void OPPROTO op_array16()
1896
{
1897
    T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1898
          (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1899
          (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1900
          (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1901
          (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1902
          (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 1;
1903
}
1904

    
1905
void OPPROTO op_array32()
1906
{
1907
    T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1908
          (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1909
          (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1910
          (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1911
          (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1912
          (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 2;
1913
}
1914

    
1915
void OPPROTO op_alignaddr()
1916
{
1917
    uint64_t tmp;
1918

    
1919
    tmp = T0 + T1;
1920
    env->gsr &= ~7ULL;
1921
    env->gsr |= tmp & 7ULL;
1922
    T0 = tmp & ~7ULL;
1923
}
1924

    
1925
void OPPROTO op_faligndata()
1926
{
1927
    uint64_t tmp;
1928

    
1929
    tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8);
1930
    tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
1931
    *((uint64_t *)&DT0) = tmp;
1932
}
1933

    
1934
void OPPROTO op_movl_FT0_0(void)
1935
{
1936
    *((uint32_t *)&FT0) = 0;
1937
}
1938

    
1939
void OPPROTO op_movl_DT0_0(void)
1940
{
1941
    *((uint64_t *)&DT0) = 0;
1942
}
1943

    
1944
void OPPROTO op_movl_FT0_1(void)
1945
{
1946
    *((uint32_t *)&FT0) = 0xffffffff;
1947
}
1948

    
1949
void OPPROTO op_movl_DT0_1(void)
1950
{
1951
    *((uint64_t *)&DT0) = 0xffffffffffffffffULL;
1952
}
1953

    
1954
void OPPROTO op_fnot(void)
1955
{
1956
    *(uint64_t *)&DT0 = ~*(uint64_t *)&DT1;
1957
}
1958

    
1959
void OPPROTO op_fnots(void)
1960
{
1961
    *(uint32_t *)&FT0 = ~*(uint32_t *)&FT1;
1962
}
1963

    
1964
void OPPROTO op_fnor(void)
1965
{
1966
    *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 | *(uint64_t *)&DT1);
1967
}
1968

    
1969
void OPPROTO op_fnors(void)
1970
{
1971
    *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 | *(uint32_t *)&FT1);
1972
}
1973

    
1974
void OPPROTO op_for(void)
1975
{
1976
    *(uint64_t *)&DT0 |= *(uint64_t *)&DT1;
1977
}
1978

    
1979
void OPPROTO op_fors(void)
1980
{
1981
    *(uint32_t *)&FT0 |= *(uint32_t *)&FT1;
1982
}
1983

    
1984
void OPPROTO op_fxor(void)
1985
{
1986
    *(uint64_t *)&DT0 ^= *(uint64_t *)&DT1;
1987
}
1988

    
1989
void OPPROTO op_fxors(void)
1990
{
1991
    *(uint32_t *)&FT0 ^= *(uint32_t *)&FT1;
1992
}
1993

    
1994
void OPPROTO op_fand(void)
1995
{
1996
    *(uint64_t *)&DT0 &= *(uint64_t *)&DT1;
1997
}
1998

    
1999
void OPPROTO op_fands(void)
2000
{
2001
    *(uint32_t *)&FT0 &= *(uint32_t *)&FT1;
2002
}
2003

    
2004
void OPPROTO op_fornot(void)
2005
{
2006
    *(uint64_t *)&DT0 = *(uint64_t *)&DT0 | ~*(uint64_t *)&DT1;
2007
}
2008

    
2009
void OPPROTO op_fornots(void)
2010
{
2011
    *(uint32_t *)&FT0 = *(uint32_t *)&FT0 | ~*(uint32_t *)&FT1;
2012
}
2013

    
2014
void OPPROTO op_fandnot(void)
2015
{
2016
    *(uint64_t *)&DT0 = *(uint64_t *)&DT0 & ~*(uint64_t *)&DT1;
2017
}
2018

    
2019
void OPPROTO op_fandnots(void)
2020
{
2021
    *(uint32_t *)&FT0 = *(uint32_t *)&FT0 & ~*(uint32_t *)&FT1;
2022
}
2023

    
2024
void OPPROTO op_fnand(void)
2025
{
2026
    *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 & *(uint64_t *)&DT1);
2027
}
2028

    
2029
void OPPROTO op_fnands(void)
2030
{
2031
    *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 & *(uint32_t *)&FT1);
2032
}
2033

    
2034
void OPPROTO op_fxnor(void)
2035
{
2036
    *(uint64_t *)&DT0 ^= ~*(uint64_t *)&DT1;
2037
}
2038

    
2039
void OPPROTO op_fxnors(void)
2040
{
2041
    *(uint32_t *)&FT0 ^= ~*(uint32_t *)&FT1;
2042
}
2043

    
2044
#ifdef WORDS_BIGENDIAN
2045
#define VIS_B64(n) b[7 - (n)]
2046
#define VIS_W64(n) w[3 - (n)]
2047
#define VIS_SW64(n) sw[3 - (n)]
2048
#define VIS_L64(n) l[1 - (n)]
2049
#define VIS_B32(n) b[3 - (n)]
2050
#define VIS_W32(n) w[1 - (n)]
2051
#else
2052
#define VIS_B64(n) b[n]
2053
#define VIS_W64(n) w[n]
2054
#define VIS_SW64(n) sw[n]
2055
#define VIS_L64(n) l[n]
2056
#define VIS_B32(n) b[n]
2057
#define VIS_W32(n) w[n]
2058
#endif
2059

    
2060
typedef union {
2061
    uint8_t b[8];
2062
    uint16_t w[4];
2063
    int16_t sw[4];
2064
    uint32_t l[2];
2065
    float64 d;
2066
} vis64;
2067

    
2068
typedef union {
2069
    uint8_t b[4];
2070
    uint16_t w[2];
2071
    uint32_t l;
2072
    float32 f;
2073
} vis32;
2074

    
2075
void OPPROTO op_fpmerge(void)
2076
{
2077
    vis64 s, d;
2078

    
2079
    s.d = DT0;
2080
    d.d = DT1;
2081

    
2082
    // Reverse calculation order to handle overlap
2083
    d.VIS_B64(7) = s.VIS_B64(3);
2084
    d.VIS_B64(6) = d.VIS_B64(3);
2085
    d.VIS_B64(5) = s.VIS_B64(2);
2086
    d.VIS_B64(4) = d.VIS_B64(2);
2087
    d.VIS_B64(3) = s.VIS_B64(1);
2088
    d.VIS_B64(2) = d.VIS_B64(1);
2089
    d.VIS_B64(1) = s.VIS_B64(0);
2090
    //d.VIS_B64(0) = d.VIS_B64(0);
2091

    
2092
    DT0 = d.d;
2093
}
2094

    
2095
void OPPROTO op_fmul8x16(void)
2096
{
2097
    vis64 s, d;
2098
    uint32_t tmp;
2099

    
2100
    s.d = DT0;
2101
    d.d = DT1;
2102

    
2103
#define PMUL(r)                                                 \
2104
    tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r);       \
2105
    if ((tmp & 0xff) > 0x7f)                                    \
2106
        tmp += 0x100;                                           \
2107
    d.VIS_W64(r) = tmp >> 8;
2108

    
2109
    PMUL(0);
2110
    PMUL(1);
2111
    PMUL(2);
2112
    PMUL(3);
2113
#undef PMUL
2114

    
2115
    DT0 = d.d;
2116
}
2117

    
2118
void OPPROTO op_fmul8x16al(void)
2119
{
2120
    vis64 s, d;
2121
    uint32_t tmp;
2122

    
2123
    s.d = DT0;
2124
    d.d = DT1;
2125

    
2126
#define PMUL(r)                                                 \
2127
    tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r);       \
2128
    if ((tmp & 0xff) > 0x7f)                                    \
2129
        tmp += 0x100;                                           \
2130
    d.VIS_W64(r) = tmp >> 8;
2131

    
2132
    PMUL(0);
2133
    PMUL(1);
2134
    PMUL(2);
2135
    PMUL(3);
2136
#undef PMUL
2137

    
2138
    DT0 = d.d;
2139
}
2140

    
2141
void OPPROTO op_fmul8x16au(void)
2142
{
2143
    vis64 s, d;
2144
    uint32_t tmp;
2145

    
2146
    s.d = DT0;
2147
    d.d = DT1;
2148

    
2149
#define PMUL(r)                                                 \
2150
    tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r);       \
2151
    if ((tmp & 0xff) > 0x7f)                                    \
2152
        tmp += 0x100;                                           \
2153
    d.VIS_W64(r) = tmp >> 8;
2154

    
2155
    PMUL(0);
2156
    PMUL(1);
2157
    PMUL(2);
2158
    PMUL(3);
2159
#undef PMUL
2160

    
2161
    DT0 = d.d;
2162
}
2163

    
2164
void OPPROTO op_fmul8sux16(void)
2165
{
2166
    vis64 s, d;
2167
    uint32_t tmp;
2168

    
2169
    s.d = DT0;
2170
    d.d = DT1;
2171

    
2172
#define PMUL(r)                                                         \
2173
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
2174
    if ((tmp & 0xff) > 0x7f)                                            \
2175
        tmp += 0x100;                                                   \
2176
    d.VIS_W64(r) = tmp >> 8;
2177

    
2178
    PMUL(0);
2179
    PMUL(1);
2180
    PMUL(2);
2181
    PMUL(3);
2182
#undef PMUL
2183

    
2184
    DT0 = d.d;
2185
}
2186

    
2187
void OPPROTO op_fmul8ulx16(void)
2188
{
2189
    vis64 s, d;
2190
    uint32_t tmp;
2191

    
2192
    s.d = DT0;
2193
    d.d = DT1;
2194

    
2195
#define PMUL(r)                                                         \
2196
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
2197
    if ((tmp & 0xff) > 0x7f)                                            \
2198
        tmp += 0x100;                                                   \
2199
    d.VIS_W64(r) = tmp >> 8;
2200

    
2201
    PMUL(0);
2202
    PMUL(1);
2203
    PMUL(2);
2204
    PMUL(3);
2205
#undef PMUL
2206

    
2207
    DT0 = d.d;
2208
}
2209

    
2210
void OPPROTO op_fmuld8sux16(void)
2211
{
2212
    vis64 s, d;
2213
    uint32_t tmp;
2214

    
2215
    s.d = DT0;
2216
    d.d = DT1;
2217

    
2218
#define PMUL(r)                                                         \
2219
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
2220
    if ((tmp & 0xff) > 0x7f)                                            \
2221
        tmp += 0x100;                                                   \
2222
    d.VIS_L64(r) = tmp;
2223

    
2224
    // Reverse calculation order to handle overlap
2225
    PMUL(1);
2226
    PMUL(0);
2227
#undef PMUL
2228

    
2229
    DT0 = d.d;
2230
}
2231

    
2232
void OPPROTO op_fmuld8ulx16(void)
2233
{
2234
    vis64 s, d;
2235
    uint32_t tmp;
2236

    
2237
    s.d = DT0;
2238
    d.d = DT1;
2239

    
2240
#define PMUL(r)                                                         \
2241
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
2242
    if ((tmp & 0xff) > 0x7f)                                            \
2243
        tmp += 0x100;                                                   \
2244
    d.VIS_L64(r) = tmp;
2245

    
2246
    // Reverse calculation order to handle overlap
2247
    PMUL(1);
2248
    PMUL(0);
2249
#undef PMUL
2250

    
2251
    DT0 = d.d;
2252
}
2253

    
2254
void OPPROTO op_fexpand(void)
2255
{
2256
    vis32 s;
2257
    vis64 d;
2258

    
2259
    s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff);
2260
    d.d = DT1;
2261
    d.VIS_L64(0) = s.VIS_W32(0) << 4;
2262
    d.VIS_L64(1) = s.VIS_W32(1) << 4;
2263
    d.VIS_L64(2) = s.VIS_W32(2) << 4;
2264
    d.VIS_L64(3) = s.VIS_W32(3) << 4;
2265

    
2266
    DT0 = d.d;
2267
}
2268

    
2269
#define VIS_OP(name, F)                                 \
2270
    void OPPROTO name##16(void)                         \
2271
    {                                                   \
2272
        vis64 s, d;                                     \
2273
                                                        \
2274
        s.d = DT0;                                      \
2275
        d.d = DT1;                                      \
2276
                                                        \
2277
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0));   \
2278
        d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1));   \
2279
        d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2));   \
2280
        d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3));   \
2281
                                                        \
2282
        DT0 = d.d;                                      \
2283
    }                                                   \
2284
                                                        \
2285
    void OPPROTO name##16s(void)                        \
2286
    {                                                   \
2287
        vis32 s, d;                                     \
2288
                                                        \
2289
        s.f = FT0;                                      \
2290
        d.f = FT1;                                      \
2291
                                                        \
2292
        d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0));   \
2293
        d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1));   \
2294
                                                        \
2295
        FT0 = d.f;                                      \
2296
    }                                                   \
2297
                                                        \
2298
    void OPPROTO name##32(void)                         \
2299
    {                                                   \
2300
        vis64 s, d;                                     \
2301
                                                        \
2302
        s.d = DT0;                                      \
2303
        d.d = DT1;                                      \
2304
                                                        \
2305
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0));   \
2306
        d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1));   \
2307
                                                        \
2308
        DT0 = d.d;                                      \
2309
    }                                                   \
2310
                                                        \
2311
    void OPPROTO name##32s(void)                        \
2312
    {                                                   \
2313
        vis32 s, d;                                     \
2314
                                                        \
2315
        s.f = FT0;                                      \
2316
        d.f = FT1;                                      \
2317
                                                        \
2318
        d.l = F(d.l, s.l);                              \
2319
                                                        \
2320
        FT0 = d.f;                                      \
2321
    }
2322

    
2323
#define FADD(a, b) ((a) + (b))
2324
#define FSUB(a, b) ((a) - (b))
2325
VIS_OP(op_fpadd, FADD)
2326
VIS_OP(op_fpsub, FSUB)
2327

    
2328
#define VIS_CMPOP(name, F)                                        \
2329
    void OPPROTO name##16(void)                                   \
2330
    {                                                             \
2331
        vis64 s, d;                                               \
2332
                                                                  \
2333
        s.d = DT0;                                                \
2334
        d.d = DT1;                                                \
2335
                                                                  \
2336
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0;       \
2337
        d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0;      \
2338
        d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0;      \
2339
        d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0;      \
2340
                                                                  \
2341
        DT0 = d.d;                                                \
2342
    }                                                             \
2343
                                                                  \
2344
    void OPPROTO name##32(void)                                   \
2345
    {                                                             \
2346
        vis64 s, d;                                               \
2347
                                                                  \
2348
        s.d = DT0;                                                \
2349
        d.d = DT1;                                                \
2350
                                                                  \
2351
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0;       \
2352
        d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0;      \
2353
                                                                  \
2354
        DT0 = d.d;                                                \
2355
    }
2356

    
2357
#define FCMPGT(a, b) ((a) > (b))
2358
#define FCMPEQ(a, b) ((a) == (b))
2359
#define FCMPLE(a, b) ((a) <= (b))
2360
#define FCMPNE(a, b) ((a) != (b))
2361

    
2362
VIS_CMPOP(op_fcmpgt, FCMPGT)
2363
VIS_CMPOP(op_fcmpeq, FCMPEQ)
2364
VIS_CMPOP(op_fcmple, FCMPLE)
2365
VIS_CMPOP(op_fcmpne, FCMPNE)
2366

    
2367
#endif
2368

    
2369
#define CHECK_ALIGN_OP(align)                           \
2370
    void OPPROTO op_check_align_T0_ ## align (void)     \
2371
    {                                                   \
2372
        if (T0 & align)                                 \
2373
            raise_exception(TT_UNALIGNED);              \
2374
        FORCE_RET();                                    \
2375
    }
2376

    
2377
CHECK_ALIGN_OP(1)
2378
CHECK_ALIGN_OP(3)
2379
CHECK_ALIGN_OP(7)