Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (47.3 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
#include "helper.h"
23

    
24
#define REGNAME f0
25
#define REG (env->fpr[0])
26
#include "fop_template.h"
27
#define REGNAME f1
28
#define REG (env->fpr[1])
29
#include "fop_template.h"
30
#define REGNAME f2
31
#define REG (env->fpr[2])
32
#include "fop_template.h"
33
#define REGNAME f3
34
#define REG (env->fpr[3])
35
#include "fop_template.h"
36
#define REGNAME f4
37
#define REG (env->fpr[4])
38
#include "fop_template.h"
39
#define REGNAME f5
40
#define REG (env->fpr[5])
41
#include "fop_template.h"
42
#define REGNAME f6
43
#define REG (env->fpr[6])
44
#include "fop_template.h"
45
#define REGNAME f7
46
#define REG (env->fpr[7])
47
#include "fop_template.h"
48
#define REGNAME f8
49
#define REG (env->fpr[8])
50
#include "fop_template.h"
51
#define REGNAME f9
52
#define REG (env->fpr[9])
53
#include "fop_template.h"
54
#define REGNAME f10
55
#define REG (env->fpr[10])
56
#include "fop_template.h"
57
#define REGNAME f11
58
#define REG (env->fpr[11])
59
#include "fop_template.h"
60
#define REGNAME f12
61
#define REG (env->fpr[12])
62
#include "fop_template.h"
63
#define REGNAME f13
64
#define REG (env->fpr[13])
65
#include "fop_template.h"
66
#define REGNAME f14
67
#define REG (env->fpr[14])
68
#include "fop_template.h"
69
#define REGNAME f15
70
#define REG (env->fpr[15])
71
#include "fop_template.h"
72
#define REGNAME f16
73
#define REG (env->fpr[16])
74
#include "fop_template.h"
75
#define REGNAME f17
76
#define REG (env->fpr[17])
77
#include "fop_template.h"
78
#define REGNAME f18
79
#define REG (env->fpr[18])
80
#include "fop_template.h"
81
#define REGNAME f19
82
#define REG (env->fpr[19])
83
#include "fop_template.h"
84
#define REGNAME f20
85
#define REG (env->fpr[20])
86
#include "fop_template.h"
87
#define REGNAME f21
88
#define REG (env->fpr[21])
89
#include "fop_template.h"
90
#define REGNAME f22
91
#define REG (env->fpr[22])
92
#include "fop_template.h"
93
#define REGNAME f23
94
#define REG (env->fpr[23])
95
#include "fop_template.h"
96
#define REGNAME f24
97
#define REG (env->fpr[24])
98
#include "fop_template.h"
99
#define REGNAME f25
100
#define REG (env->fpr[25])
101
#include "fop_template.h"
102
#define REGNAME f26
103
#define REG (env->fpr[26])
104
#include "fop_template.h"
105
#define REGNAME f27
106
#define REG (env->fpr[27])
107
#include "fop_template.h"
108
#define REGNAME f28
109
#define REG (env->fpr[28])
110
#include "fop_template.h"
111
#define REGNAME f29
112
#define REG (env->fpr[29])
113
#include "fop_template.h"
114
#define REGNAME f30
115
#define REG (env->fpr[30])
116
#include "fop_template.h"
117
#define REGNAME f31
118
#define REG (env->fpr[31])
119
#include "fop_template.h"
120

    
121
#ifdef TARGET_SPARC64
122
#define REGNAME f32
123
#define REG (env->fpr[32])
124
#include "fop_template.h"
125
#define REGNAME f34
126
#define REG (env->fpr[34])
127
#include "fop_template.h"
128
#define REGNAME f36
129
#define REG (env->fpr[36])
130
#include "fop_template.h"
131
#define REGNAME f38
132
#define REG (env->fpr[38])
133
#include "fop_template.h"
134
#define REGNAME f40
135
#define REG (env->fpr[40])
136
#include "fop_template.h"
137
#define REGNAME f42
138
#define REG (env->fpr[42])
139
#include "fop_template.h"
140
#define REGNAME f44
141
#define REG (env->fpr[44])
142
#include "fop_template.h"
143
#define REGNAME f46
144
#define REG (env->fpr[46])
145
#include "fop_template.h"
146
#define REGNAME f48
147
#define REG (env->fpr[47])
148
#include "fop_template.h"
149
#define REGNAME f50
150
#define REG (env->fpr[50])
151
#include "fop_template.h"
152
#define REGNAME f52
153
#define REG (env->fpr[52])
154
#include "fop_template.h"
155
#define REGNAME f54
156
#define REG (env->fpr[54])
157
#include "fop_template.h"
158
#define REGNAME f56
159
#define REG (env->fpr[56])
160
#include "fop_template.h"
161
#define REGNAME f58
162
#define REG (env->fpr[58])
163
#include "fop_template.h"
164
#define REGNAME f60
165
#define REG (env->fpr[60])
166
#include "fop_template.h"
167
#define REGNAME f62
168
#define REG (env->fpr[62])
169
#include "fop_template.h"
170
#endif
171

    
172
#ifdef TARGET_SPARC64
173
#define XFLAG_SET(x) ((env->xcc&x)?1:0)
174
#endif
175

    
176
#define FLAG_SET(x) ((env->psr&x)?1:0)
177

    
178
void OPPROTO op_add_T1_T0_cc(void)
179
{
180
    target_ulong src1;
181

    
182
    src1 = T0;
183
    T0 += T1;
184
    env->psr = 0;
185
#ifdef TARGET_SPARC64
186
    if (!(T0 & 0xffffffff))
187
        env->psr |= PSR_ZERO;
188
    if ((int32_t) T0 < 0)
189
        env->psr |= PSR_NEG;
190
    if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
191
        env->psr |= PSR_CARRY;
192
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
193
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
194
        env->psr |= PSR_OVF;
195

    
196
    env->xcc = 0;
197
    if (!T0)
198
        env->xcc |= PSR_ZERO;
199
    if ((int64_t) T0 < 0)
200
        env->xcc |= PSR_NEG;
201
    if (T0 < src1)
202
        env->xcc |= PSR_CARRY;
203
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
204
        env->xcc |= PSR_OVF;
205
#else
206
    if (!T0)
207
        env->psr |= PSR_ZERO;
208
    if ((int32_t) T0 < 0)
209
        env->psr |= PSR_NEG;
210
    if (T0 < src1)
211
        env->psr |= PSR_CARRY;
212
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
213
        env->psr |= PSR_OVF;
214
#endif
215
    FORCE_RET();
216
}
217

    
218
void OPPROTO op_addx_T1_T0(void)
219
{
220
    T0 += T1 + FLAG_SET(PSR_CARRY);
221
}
222

    
223
void OPPROTO op_addx_T1_T0_cc(void)
224
{
225
    target_ulong src1;
226
    src1 = T0;
227
    if (FLAG_SET(PSR_CARRY))
228
    {
229
      T0 += T1 + 1;
230
      env->psr = 0;
231
#ifdef TARGET_SPARC64
232
      if ((T0 & 0xffffffff) <= (src1 & 0xffffffff))
233
        env->psr |= PSR_CARRY;
234
      env->xcc = 0;
235
      if (T0 <= src1)
236
        env->xcc |= PSR_CARRY;
237
#else
238
      if (T0 <= src1)
239
        env->psr |= PSR_CARRY;
240
#endif
241
    }
242
    else
243
    {
244
      T0 += T1;
245
      env->psr = 0;
246
#ifdef TARGET_SPARC64
247
      if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
248
        env->psr |= PSR_CARRY;
249
      env->xcc = 0;
250
      if (T0 < src1)
251
        env->xcc |= PSR_CARRY;
252
#else
253
      if (T0 < src1)
254
        env->psr |= PSR_CARRY;
255
#endif
256
    }
257
#ifdef TARGET_SPARC64
258
    if (!(T0 & 0xffffffff))
259
        env->psr |= PSR_ZERO;
260
    if ((int32_t) T0 < 0)
261
        env->psr |= PSR_NEG;
262
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
263
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
264
        env->psr |= PSR_OVF;
265

    
266
    if (!T0)
267
        env->xcc |= PSR_ZERO;
268
    if ((int64_t) T0 < 0)
269
        env->xcc |= PSR_NEG;
270
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
271
        env->xcc |= PSR_OVF;
272
#else
273
    if (!T0)
274
        env->psr |= PSR_ZERO;
275
    if ((int32_t) T0 < 0)
276
        env->psr |= PSR_NEG;
277
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
278
        env->psr |= PSR_OVF;
279
#endif
280
    FORCE_RET();
281
}
282

    
283
void OPPROTO op_tadd_T1_T0_cc(void)
284
{
285
    target_ulong src1;
286

    
287
    src1 = T0;
288
    T0 += T1;
289
    env->psr = 0;
290
#ifdef TARGET_SPARC64
291
    if (!(T0 & 0xffffffff))
292
        env->psr |= PSR_ZERO;
293
    if ((int32_t) T0 < 0)
294
        env->psr |= PSR_NEG;
295
    if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
296
        env->psr |= PSR_CARRY;
297
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
298
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
299
        env->psr |= PSR_OVF;
300
    if ((src1 & 0x03) || (T1 & 0x03))
301
        env->psr |= PSR_OVF;
302

    
303
    env->xcc = 0;
304
    if (!T0)
305
        env->xcc |= PSR_ZERO;
306
    if ((int64_t) T0 < 0)
307
        env->xcc |= PSR_NEG;
308
    if (T0 < src1)
309
        env->xcc |= PSR_CARRY;
310
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
311
        env->xcc |= PSR_OVF;
312
#else
313
    if (!T0)
314
        env->psr |= PSR_ZERO;
315
    if ((int32_t) T0 < 0)
316
        env->psr |= PSR_NEG;
317
    if (T0 < src1)
318
        env->psr |= PSR_CARRY;
319
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
320
        env->psr |= PSR_OVF;
321
    if ((src1 & 0x03) || (T1 & 0x03))
322
        env->psr |= PSR_OVF;
323
#endif
324
    FORCE_RET();
325
}
326

    
327
void OPPROTO op_tadd_T1_T0_ccTV(void)
328
{
329
    target_ulong src1;
330

    
331
    if ((T0 & 0x03) || (T1 & 0x03)) {
332
        raise_exception(TT_TOVF);
333
        FORCE_RET();
334
        return;
335
    }
336

    
337
    src1 = T0;
338
    T0 += T1;
339

    
340
#ifdef TARGET_SPARC64
341
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
342
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
343
        raise_exception(TT_TOVF);
344
#else
345
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
346
        raise_exception(TT_TOVF);
347
#endif
348

    
349
    env->psr = 0;
350
#ifdef TARGET_SPARC64
351
    if (!(T0 & 0xffffffff))
352
        env->psr |= PSR_ZERO;
353
    if ((int32_t) T0 < 0)
354
        env->psr |= PSR_NEG;
355
    if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
356
        env->psr |= PSR_CARRY;
357

    
358
    env->xcc = 0;
359
    if (!T0)
360
        env->xcc |= PSR_ZERO;
361
    if ((int64_t) T0 < 0)
362
        env->xcc |= PSR_NEG;
363
    if (T0 < src1)
364
        env->xcc |= PSR_CARRY;
365
#else
366
    if (!T0)
367
        env->psr |= PSR_ZERO;
368
    if ((int32_t) T0 < 0)
369
        env->psr |= PSR_NEG;
370
    if (T0 < src1)
371
        env->psr |= PSR_CARRY;
372
#endif
373
    FORCE_RET();
374
}
375

    
376
void OPPROTO op_sub_T1_T0_cc(void)
377
{
378
    target_ulong src1;
379

    
380
    src1 = T0;
381
    T0 -= T1;
382
    env->psr = 0;
383
#ifdef TARGET_SPARC64
384
    if (!(T0 & 0xffffffff))
385
        env->psr |= PSR_ZERO;
386
    if ((int32_t) T0 < 0)
387
        env->psr |= PSR_NEG;
388
    if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
389
        env->psr |= PSR_CARRY;
390
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
391
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
392
        env->psr |= PSR_OVF;
393

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

    
416
void OPPROTO op_subx_T1_T0(void)
417
{
418
    T0 -= T1 + FLAG_SET(PSR_CARRY);
419
}
420

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

    
464
    if (!T0)
465
        env->xcc |= PSR_ZERO;
466
    if ((int64_t) T0 < 0)
467
        env->xcc |= PSR_NEG;
468
    if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
469
        env->xcc |= PSR_OVF;
470
#else
471
    if (!T0)
472
        env->psr |= PSR_ZERO;
473
    if ((int32_t) T0 < 0)
474
        env->psr |= PSR_NEG;
475
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
476
        env->psr |= PSR_OVF;
477
#endif
478
    FORCE_RET();
479
}
480

    
481
void OPPROTO op_tsub_T1_T0_cc(void)
482
{
483
    target_ulong src1;
484

    
485
    src1 = T0;
486
    T0 -= T1;
487
    env->psr = 0;
488
#ifdef TARGET_SPARC64
489
    if (!(T0 & 0xffffffff))
490
        env->psr |= PSR_ZERO;
491
    if ((int32_t) T0 < 0)
492
        env->psr |= PSR_NEG;
493
    if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
494
        env->psr |= PSR_CARRY;
495
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
496
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
497
        env->psr |= PSR_OVF;
498
    if ((src1 & 0x03) || (T1 & 0x03))
499
        env->psr |= PSR_OVF;
500

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

    
525
void OPPROTO op_tsub_T1_T0_ccTV(void)
526
{
527
    target_ulong src1;
528

    
529
    if ((T0 & 0x03) || (T1 & 0x03))
530
        raise_exception(TT_TOVF);
531

    
532
    src1 = T0;
533
    T0 -= T1;
534

    
535
#ifdef TARGET_SPARC64
536
    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
537
         ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
538
        raise_exception(TT_TOVF);
539
#else
540
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
541
        raise_exception(TT_TOVF);
542
#endif
543

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

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

    
571
void OPPROTO op_andn_T1_T0(void)
572
{
573
    T0 &= ~T1;
574
}
575

    
576
void OPPROTO op_orn_T1_T0(void)
577
{
578
    T0 |= ~T1;
579
}
580

    
581
void OPPROTO op_xnor_T1_T0(void)
582
{
583
    T0 ^= ~T1;
584
}
585

    
586
void OPPROTO op_umul_T1_T0(void)
587
{
588
    uint64_t res;
589
    res = (uint64_t) T0 * (uint64_t) T1;
590
#ifdef TARGET_SPARC64
591
    T0 = res;
592
#else
593
    T0 = res & 0xffffffff;
594
#endif
595
    env->y = res >> 32;
596
}
597

    
598
void OPPROTO op_smul_T1_T0(void)
599
{
600
    uint64_t res;
601
    res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
602
#ifdef TARGET_SPARC64
603
    T0 = res;
604
#else
605
    T0 = res & 0xffffffff;
606
#endif
607
    env->y = res >> 32;
608
}
609

    
610
void OPPROTO op_mulscc_T1_T0(void)
611
{
612
    unsigned int b1, N, V, b2;
613
    target_ulong src1;
614

    
615
    N = FLAG_SET(PSR_NEG);
616
    V = FLAG_SET(PSR_OVF);
617
    b1 = N ^ V;
618
    b2 = T0 & 1;
619
    T0 = (b1 << 31) | (T0 >> 1);
620
    if (!(env->y & 1))
621
        T1 = 0;
622
    /* do addition and update flags */
623
    src1 = T0;
624
    T0 += T1;
625
    env->psr = 0;
626
    if (!T0)
627
        env->psr |= PSR_ZERO;
628
    if ((int32_t) T0 < 0)
629
        env->psr |= PSR_NEG;
630
    if (T0 < src1)
631
        env->psr |= PSR_CARRY;
632
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
633
        env->psr |= PSR_OVF;
634
    env->y = (b2 << 31) | (env->y >> 1);
635
    FORCE_RET();
636
}
637

    
638
void OPPROTO op_udiv_T1_T0(void)
639
{
640
    uint64_t x0;
641
    uint32_t x1;
642

    
643
    x0 = T0 | ((uint64_t) (env->y) << 32);
644
    x1 = T1;
645

    
646
    if (x1 == 0) {
647
        raise_exception(TT_DIV_ZERO);
648
    }
649

    
650
    x0 = x0 / x1;
651
    if (x0 > 0xffffffff) {
652
        T0 = 0xffffffff;
653
        T1 = 1;
654
    } else {
655
        T0 = x0;
656
        T1 = 0;
657
    }
658
    FORCE_RET();
659
}
660

    
661
void OPPROTO op_sdiv_T1_T0(void)
662
{
663
    int64_t x0;
664
    int32_t x1;
665

    
666
    x0 = T0 | ((int64_t) (env->y) << 32);
667
    x1 = T1;
668

    
669
    if (x1 == 0) {
670
        raise_exception(TT_DIV_ZERO);
671
    }
672

    
673
    x0 = x0 / x1;
674
    if ((int32_t) x0 != x0) {
675
        T0 = x0 < 0? 0x80000000: 0x7fffffff;
676
        T1 = 1;
677
    } else {
678
        T0 = x0;
679
        T1 = 0;
680
    }
681
    FORCE_RET();
682
}
683

    
684
void OPPROTO op_div_cc(void)
685
{
686
    env->psr = 0;
687
#ifdef TARGET_SPARC64
688
    if (!T0)
689
        env->psr |= PSR_ZERO;
690
    if ((int32_t) T0 < 0)
691
        env->psr |= PSR_NEG;
692
    if (T1)
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
#else
701
    if (!T0)
702
        env->psr |= PSR_ZERO;
703
    if ((int32_t) T0 < 0)
704
        env->psr |= PSR_NEG;
705
    if (T1)
706
        env->psr |= PSR_OVF;
707
#endif
708
    FORCE_RET();
709
}
710

    
711
#ifdef TARGET_SPARC64
712
void OPPROTO op_udivx_T1_T0(void)
713
{
714
    if (T1 == 0) {
715
        raise_exception(TT_DIV_ZERO);
716
    }
717
    T0 /= T1;
718
    FORCE_RET();
719
}
720

    
721
void OPPROTO op_sdivx_T1_T0(void)
722
{
723
    if (T1 == 0) {
724
        raise_exception(TT_DIV_ZERO);
725
    }
726
    if (T0 == INT64_MIN && T1 == -1)
727
        T0 = INT64_MIN;
728
    else
729
        T0 /= (target_long) T1;
730
    FORCE_RET();
731
}
732
#endif
733

    
734
void OPPROTO op_logic_T0_cc(void)
735
{
736
    env->psr = 0;
737
#ifdef TARGET_SPARC64
738
    if (!(T0 & 0xffffffff))
739
        env->psr |= PSR_ZERO;
740
    if ((int32_t) T0 < 0)
741
        env->psr |= PSR_NEG;
742

    
743
    env->xcc = 0;
744
    if (!T0)
745
        env->xcc |= PSR_ZERO;
746
    if ((int64_t) T0 < 0)
747
        env->xcc |= PSR_NEG;
748
#else
749
    if (!T0)
750
        env->psr |= PSR_ZERO;
751
    if ((int32_t) T0 < 0)
752
        env->psr |= PSR_NEG;
753
#endif
754
    FORCE_RET();
755
}
756

    
757
/* Load and store */
758
#define MEMSUFFIX _raw
759
#include "op_mem.h"
760
#if !defined(CONFIG_USER_ONLY)
761
#define MEMSUFFIX _user
762
#include "op_mem.h"
763

    
764
#define MEMSUFFIX _kernel
765
#include "op_mem.h"
766

    
767
#ifdef TARGET_SPARC64
768
#define MEMSUFFIX _hypv
769
#include "op_mem.h"
770
#endif
771
#endif
772

    
773
void OPPROTO op_ldfsr(void)
774
{
775
    PUT_FSR32(env, *((uint32_t *) &FT0));
776
    helper_ldfsr();
777
}
778

    
779
void OPPROTO op_stfsr(void)
780
{
781
    *((uint32_t *) &FT0) = GET_FSR32(env);
782
}
783

    
784
#ifndef TARGET_SPARC64
785
/* XXX: use another pointer for %iN registers to avoid slow wrapping
786
   handling ? */
787
void OPPROTO op_save(void)
788
{
789
    uint32_t cwp;
790
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
791
    if (env->wim & (1 << cwp)) {
792
        raise_exception(TT_WIN_OVF);
793
    }
794
    set_cwp(cwp);
795
    FORCE_RET();
796
}
797

    
798
void OPPROTO op_restore(void)
799
{
800
    uint32_t cwp;
801
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
802
    if (env->wim & (1 << cwp)) {
803
        raise_exception(TT_WIN_UNF);
804
    }
805
    set_cwp(cwp);
806
    FORCE_RET();
807
}
808
#else
809
void OPPROTO op_rdccr(void)
810
{
811
    T0 = GET_CCR(env);
812
}
813

    
814
void OPPROTO op_wrccr(void)
815
{
816
    PUT_CCR(env, T0);
817
}
818

    
819
void OPPROTO op_rdtick(void)
820
{
821
    T0 = do_tick_get_count(env->tick);
822
}
823

    
824
void OPPROTO op_wrtick(void)
825
{
826
    do_tick_set_count(env->tick, T0);
827
}
828

    
829
void OPPROTO op_wrtick_cmpr(void)
830
{
831
    do_tick_set_limit(env->tick, T0);
832
}
833

    
834
void OPPROTO op_rdstick(void)
835
{
836
    T0 = do_tick_get_count(env->stick);
837
}
838

    
839
void OPPROTO op_wrstick(void)
840
{
841
    do_tick_set_count(env->stick, T0);
842
    do_tick_set_count(env->hstick, T0);
843
}
844

    
845
void OPPROTO op_wrstick_cmpr(void)
846
{
847
    do_tick_set_limit(env->stick, T0);
848
}
849

    
850
void OPPROTO op_wrhstick_cmpr(void)
851
{
852
    do_tick_set_limit(env->hstick, T0);
853
}
854

    
855
void OPPROTO op_rdtpc(void)
856
{
857
    T0 = env->tpc[env->tl];
858
}
859

    
860
void OPPROTO op_wrtpc(void)
861
{
862
    env->tpc[env->tl] = T0;
863
}
864

    
865
void OPPROTO op_rdtnpc(void)
866
{
867
    T0 = env->tnpc[env->tl];
868
}
869

    
870
void OPPROTO op_wrtnpc(void)
871
{
872
    env->tnpc[env->tl] = T0;
873
}
874

    
875
void OPPROTO op_rdtstate(void)
876
{
877
    T0 = env->tstate[env->tl];
878
}
879

    
880
void OPPROTO op_wrtstate(void)
881
{
882
    env->tstate[env->tl] = T0;
883
}
884

    
885
void OPPROTO op_rdtt(void)
886
{
887
    T0 = env->tt[env->tl];
888
}
889

    
890
void OPPROTO op_wrtt(void)
891
{
892
    env->tt[env->tl] = T0;
893
}
894

    
895
// CWP handling is reversed in V9, but we still use the V8 register
896
// order.
897
void OPPROTO op_rdcwp(void)
898
{
899
    T0 = GET_CWP64(env);
900
}
901

    
902
void OPPROTO op_wrcwp(void)
903
{
904
    PUT_CWP64(env, T0);
905
}
906

    
907
/* XXX: use another pointer for %iN registers to avoid slow wrapping
908
   handling ? */
909
void OPPROTO op_save(void)
910
{
911
    uint32_t cwp;
912
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
913
    if (env->cansave == 0) {
914
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
915
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
916
                                    ((env->wstate & 0x7) << 2)));
917
    } else {
918
        if (env->cleanwin - env->canrestore == 0) {
919
            // XXX Clean windows without trap
920
            raise_exception(TT_CLRWIN);
921
        } else {
922
            env->cansave--;
923
            env->canrestore++;
924
            set_cwp(cwp);
925
        }
926
    }
927
    FORCE_RET();
928
}
929

    
930
void OPPROTO op_restore(void)
931
{
932
    uint32_t cwp;
933
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
934
    if (env->canrestore == 0) {
935
        raise_exception(TT_FILL | (env->otherwin != 0 ?
936
                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
937
                                   ((env->wstate & 0x7) << 2)));
938
    } else {
939
        env->cansave++;
940
        env->canrestore--;
941
        set_cwp(cwp);
942
    }
943
    FORCE_RET();
944
}
945
#endif
946

    
947
void OPPROTO op_exception(void)
948
{
949
    env->exception_index = PARAM1;
950
    cpu_loop_exit();
951
    FORCE_RET();
952
}
953

    
954
void OPPROTO op_fpexception_im(void)
955
{
956
    env->exception_index = TT_FP_EXCP;
957
    env->fsr &= ~FSR_FTT_MASK;
958
    env->fsr |= PARAM1;
959
    cpu_loop_exit();
960
    FORCE_RET();
961
}
962

    
963
void OPPROTO op_eval_ba(void)
964
{
965
    T2 = 1;
966
}
967

    
968
void OPPROTO op_eval_be(void)
969
{
970
    T2 = FLAG_SET(PSR_ZERO);
971
}
972

    
973
void OPPROTO op_eval_ble(void)
974
{
975
    target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
976

    
977
    T2 = Z | (N ^ V);
978
}
979

    
980
void OPPROTO op_eval_bl(void)
981
{
982
    target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
983

    
984
    T2 = N ^ V;
985
}
986

    
987
void OPPROTO op_eval_bleu(void)
988
{
989
    target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
990

    
991
    T2 = C | Z;
992
}
993

    
994
void OPPROTO op_eval_bcs(void)
995
{
996
    T2 = FLAG_SET(PSR_CARRY);
997
}
998

    
999
void OPPROTO op_eval_bvs(void)
1000
{
1001
    T2 = FLAG_SET(PSR_OVF);
1002
}
1003

    
1004
void OPPROTO op_eval_bn(void)
1005
{
1006
    T2 = 0;
1007
}
1008

    
1009
void OPPROTO op_eval_bneg(void)
1010
{
1011
    T2 = FLAG_SET(PSR_NEG);
1012
}
1013

    
1014
void OPPROTO op_eval_bne(void)
1015
{
1016
    T2 = !FLAG_SET(PSR_ZERO);
1017
}
1018

    
1019
void OPPROTO op_eval_bg(void)
1020
{
1021
    target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1022

    
1023
    T2 = !(Z | (N ^ V));
1024
}
1025

    
1026
void OPPROTO op_eval_bge(void)
1027
{
1028
    target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1029

    
1030
    T2 = !(N ^ V);
1031
}
1032

    
1033
void OPPROTO op_eval_bgu(void)
1034
{
1035
    target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1036

    
1037
    T2 = !(C | Z);
1038
}
1039

    
1040
void OPPROTO op_eval_bcc(void)
1041
{
1042
    T2 = !FLAG_SET(PSR_CARRY);
1043
}
1044

    
1045
void OPPROTO op_eval_bpos(void)
1046
{
1047
    T2 = !FLAG_SET(PSR_NEG);
1048
}
1049

    
1050
void OPPROTO op_eval_bvc(void)
1051
{
1052
    T2 = !FLAG_SET(PSR_OVF);
1053
}
1054

    
1055
#ifdef TARGET_SPARC64
1056
void OPPROTO op_eval_xbe(void)
1057
{
1058
    T2 = XFLAG_SET(PSR_ZERO);
1059
}
1060

    
1061
void OPPROTO op_eval_xble(void)
1062
{
1063
    target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1064

    
1065
    T2 = Z | (N ^ V);
1066
}
1067

    
1068
void OPPROTO op_eval_xbl(void)
1069
{
1070
    target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1071

    
1072
    T2 = N ^ V;
1073
}
1074

    
1075
void OPPROTO op_eval_xbleu(void)
1076
{
1077
    target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1078

    
1079
    T2 = C | Z;
1080
}
1081

    
1082
void OPPROTO op_eval_xbcs(void)
1083
{
1084
    T2 = XFLAG_SET(PSR_CARRY);
1085
}
1086

    
1087
void OPPROTO op_eval_xbvs(void)
1088
{
1089
    T2 = XFLAG_SET(PSR_OVF);
1090
}
1091

    
1092
void OPPROTO op_eval_xbneg(void)
1093
{
1094
    T2 = XFLAG_SET(PSR_NEG);
1095
}
1096

    
1097
void OPPROTO op_eval_xbne(void)
1098
{
1099
    T2 = !XFLAG_SET(PSR_ZERO);
1100
}
1101

    
1102
void OPPROTO op_eval_xbg(void)
1103
{
1104
    target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1105

    
1106
    T2 = !(Z | (N ^ V));
1107
}
1108

    
1109
void OPPROTO op_eval_xbge(void)
1110
{
1111
    target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1112

    
1113
    T2 = !(N ^ V);
1114
}
1115

    
1116
void OPPROTO op_eval_xbgu(void)
1117
{
1118
    target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1119

    
1120
    T2 = !(C | Z);
1121
}
1122

    
1123
void OPPROTO op_eval_xbcc(void)
1124
{
1125
    T2 = !XFLAG_SET(PSR_CARRY);
1126
}
1127

    
1128
void OPPROTO op_eval_xbpos(void)
1129
{
1130
    T2 = !XFLAG_SET(PSR_NEG);
1131
}
1132

    
1133
void OPPROTO op_eval_xbvc(void)
1134
{
1135
    T2 = !XFLAG_SET(PSR_OVF);
1136
}
1137
#endif
1138

    
1139
#define FCC
1140
#define FFLAG_SET(x) (env->fsr & x? 1: 0)
1141
#include "fbranch_template.h"
1142

    
1143
#ifdef TARGET_SPARC64
1144
#define FCC _fcc1
1145
#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
1146
#include "fbranch_template.h"
1147
#define FCC _fcc2
1148
#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
1149
#include "fbranch_template.h"
1150
#define FCC _fcc3
1151
#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
1152
#include "fbranch_template.h"
1153
#endif
1154

    
1155
#ifdef TARGET_SPARC64
1156
void OPPROTO op_eval_brz(void)
1157
{
1158
    T2 = (T0 == 0);
1159
}
1160

    
1161
void OPPROTO op_eval_brnz(void)
1162
{
1163
    T2 = (T0 != 0);
1164
}
1165

    
1166
void OPPROTO op_eval_brlz(void)
1167
{
1168
    T2 = ((int64_t)T0 < 0);
1169
}
1170

    
1171
void OPPROTO op_eval_brlez(void)
1172
{
1173
    T2 = ((int64_t)T0 <= 0);
1174
}
1175

    
1176
void OPPROTO op_eval_brgz(void)
1177
{
1178
    T2 = ((int64_t)T0 > 0);
1179
}
1180

    
1181
void OPPROTO op_eval_brgez(void)
1182
{
1183
    T2 = ((int64_t)T0 >= 0);
1184
}
1185
#endif
1186

    
1187
void OPPROTO op_mov_pc_npc(void)
1188
{
1189
    env->pc = env->npc;
1190
}
1191

    
1192
void OPPROTO op_next_insn(void)
1193
{
1194
    env->pc = env->npc;
1195
    env->npc = env->npc + 4;
1196
}
1197

    
1198
void OPPROTO op_jmp_label(void)
1199
{
1200
    GOTO_LABEL_PARAM(1);
1201
}
1202

    
1203
void OPPROTO op_jnz_T2_label(void)
1204
{
1205
    if (T2)
1206
        GOTO_LABEL_PARAM(1);
1207
    FORCE_RET();
1208
}
1209

    
1210
void OPPROTO op_jz_T2_label(void)
1211
{
1212
    if (!T2)
1213
        GOTO_LABEL_PARAM(1);
1214
    FORCE_RET();
1215
}
1216

    
1217
void OPPROTO op_clear_ieee_excp_and_FTT(void)
1218
{
1219
    env->fsr &= ~(FSR_FTT_MASK | FSR_CEXC_MASK);;
1220
}
1221

    
1222
#define F_OP(name, p) void OPPROTO op_f##name##p(void)
1223

    
1224
#if defined(CONFIG_USER_ONLY)
1225
#define F_BINOP(name)                                           \
1226
    F_OP(name, s)                                               \
1227
    {                                                           \
1228
        set_float_exception_flags(0, &env->fp_status);          \
1229
        FT0 = float32_ ## name (FT0, FT1, &env->fp_status);     \
1230
        check_ieee_exceptions();                                \
1231
    }                                                           \
1232
    F_OP(name, d)                                               \
1233
    {                                                           \
1234
        set_float_exception_flags(0, &env->fp_status);          \
1235
        DT0 = float64_ ## name (DT0, DT1, &env->fp_status);     \
1236
        check_ieee_exceptions();                                \
1237
    }                                                           \
1238
    F_OP(name, q)                                               \
1239
    {                                                           \
1240
        set_float_exception_flags(0, &env->fp_status);          \
1241
        QT0 = float128_ ## name (QT0, QT1, &env->fp_status);    \
1242
        check_ieee_exceptions();                                \
1243
    }
1244
#else
1245
#define F_BINOP(name)                                           \
1246
    F_OP(name, s)                                               \
1247
    {                                                           \
1248
        set_float_exception_flags(0, &env->fp_status);          \
1249
        FT0 = float32_ ## name (FT0, FT1, &env->fp_status);     \
1250
        check_ieee_exceptions();                                \
1251
    }                                                           \
1252
    F_OP(name, d)                                               \
1253
    {                                                           \
1254
        set_float_exception_flags(0, &env->fp_status);          \
1255
        DT0 = float64_ ## name (DT0, DT1, &env->fp_status);     \
1256
        check_ieee_exceptions();                                \
1257
    }
1258
#endif
1259

    
1260
F_BINOP(add);
1261
F_BINOP(sub);
1262
F_BINOP(mul);
1263
F_BINOP(div);
1264
#undef F_BINOP
1265

    
1266
void OPPROTO op_fsmuld(void)
1267
{
1268
    set_float_exception_flags(0, &env->fp_status);
1269
    DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status),
1270
                      float32_to_float64(FT1, &env->fp_status),
1271
                      &env->fp_status);
1272
    check_ieee_exceptions();
1273
}
1274

    
1275
#if defined(CONFIG_USER_ONLY)
1276
void OPPROTO op_fdmulq(void)
1277
{
1278
    set_float_exception_flags(0, &env->fp_status);
1279
    QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status),
1280
                       float64_to_float128(DT1, &env->fp_status),
1281
                       &env->fp_status);
1282
    check_ieee_exceptions();
1283
}
1284
#endif
1285

    
1286
#if defined(CONFIG_USER_ONLY)
1287
#define F_HELPER(name)    \
1288
    F_OP(name, s)         \
1289
    {                     \
1290
        do_f##name##s();  \
1291
    }                     \
1292
    F_OP(name, d)         \
1293
    {                     \
1294
        do_f##name##d();  \
1295
    }                     \
1296
    F_OP(name, q)         \
1297
    {                     \
1298
        do_f##name##q();  \
1299
    }
1300
#else
1301
#define F_HELPER(name)    \
1302
    F_OP(name, s)         \
1303
    {                     \
1304
        do_f##name##s();  \
1305
    }                     \
1306
    F_OP(name, d)         \
1307
    {                     \
1308
        do_f##name##d();  \
1309
    }
1310
#endif
1311

    
1312
F_HELPER(sqrt);
1313

    
1314
F_OP(neg, s)
1315
{
1316
    FT0 = float32_chs(FT1);
1317
}
1318

    
1319
F_OP(abs, s)
1320
{
1321
    do_fabss();
1322
}
1323

    
1324
F_HELPER(cmp);
1325
F_HELPER(cmpe);
1326

    
1327
#ifdef TARGET_SPARC64
1328
F_OP(neg, d)
1329
{
1330
    DT0 = float64_chs(DT1);
1331
}
1332

    
1333
F_OP(abs, d)
1334
{
1335
    do_fabsd();
1336
}
1337

    
1338
#if defined(CONFIG_USER_ONLY)
1339
F_OP(neg, q)
1340
{
1341
    QT0 = float128_chs(QT1);
1342
}
1343

    
1344
F_OP(abs, q)
1345
{
1346
    do_fabsd();
1347
}
1348
#endif
1349

    
1350
void OPPROTO op_fcmps_fcc1(void)
1351
{
1352
    do_fcmps_fcc1();
1353
}
1354

    
1355
void OPPROTO op_fcmpd_fcc1(void)
1356
{
1357
    do_fcmpd_fcc1();
1358
}
1359

    
1360
void OPPROTO op_fcmps_fcc2(void)
1361
{
1362
    do_fcmps_fcc2();
1363
}
1364

    
1365
void OPPROTO op_fcmpd_fcc2(void)
1366
{
1367
    do_fcmpd_fcc2();
1368
}
1369

    
1370
void OPPROTO op_fcmps_fcc3(void)
1371
{
1372
    do_fcmps_fcc3();
1373
}
1374

    
1375
void OPPROTO op_fcmpd_fcc3(void)
1376
{
1377
    do_fcmpd_fcc3();
1378
}
1379

    
1380
void OPPROTO op_fcmpes_fcc1(void)
1381
{
1382
    do_fcmpes_fcc1();
1383
}
1384

    
1385
void OPPROTO op_fcmped_fcc1(void)
1386
{
1387
    do_fcmped_fcc1();
1388
}
1389

    
1390
void OPPROTO op_fcmpes_fcc2(void)
1391
{
1392
    do_fcmpes_fcc2();
1393
}
1394

    
1395
void OPPROTO op_fcmped_fcc2(void)
1396
{
1397
    do_fcmped_fcc2();
1398
}
1399

    
1400
void OPPROTO op_fcmpes_fcc3(void)
1401
{
1402
    do_fcmpes_fcc3();
1403
}
1404

    
1405
void OPPROTO op_fcmped_fcc3(void)
1406
{
1407
    do_fcmped_fcc3();
1408
}
1409

    
1410
#if defined(CONFIG_USER_ONLY)
1411
void OPPROTO op_fcmpq_fcc1(void)
1412
{
1413
    do_fcmpq_fcc1();
1414
}
1415

    
1416
void OPPROTO op_fcmpq_fcc2(void)
1417
{
1418
    do_fcmpq_fcc2();
1419
}
1420

    
1421
void OPPROTO op_fcmpq_fcc3(void)
1422
{
1423
    do_fcmpq_fcc3();
1424
}
1425

    
1426
void OPPROTO op_fcmpeq_fcc1(void)
1427
{
1428
    do_fcmpeq_fcc1();
1429
}
1430

    
1431
void OPPROTO op_fcmpeq_fcc2(void)
1432
{
1433
    do_fcmpeq_fcc2();
1434
}
1435

    
1436
void OPPROTO op_fcmpeq_fcc3(void)
1437
{
1438
    do_fcmpeq_fcc3();
1439
}
1440
#endif
1441

    
1442
#endif
1443

    
1444
/* Integer to float conversion.  */
1445
#ifdef USE_INT_TO_FLOAT_HELPERS
1446
F_HELPER(ito);
1447
#ifdef TARGET_SPARC64
1448
F_HELPER(xto);
1449
#endif
1450
#else
1451
F_OP(ito, s)
1452
{
1453
    set_float_exception_flags(0, &env->fp_status);
1454
    FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
1455
    check_ieee_exceptions();
1456
}
1457

    
1458
F_OP(ito, d)
1459
{
1460
    set_float_exception_flags(0, &env->fp_status);
1461
    DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
1462
    check_ieee_exceptions();
1463
}
1464

    
1465
#if defined(CONFIG_USER_ONLY)
1466
F_OP(ito, q)
1467
{
1468
    set_float_exception_flags(0, &env->fp_status);
1469
    QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
1470
    check_ieee_exceptions();
1471
}
1472
#endif
1473

    
1474
#ifdef TARGET_SPARC64
1475
F_OP(xto, s)
1476
{
1477
    set_float_exception_flags(0, &env->fp_status);
1478
    FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
1479
    check_ieee_exceptions();
1480
}
1481

    
1482
F_OP(xto, d)
1483
{
1484
    set_float_exception_flags(0, &env->fp_status);
1485
    DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
1486
    check_ieee_exceptions();
1487
}
1488
#if defined(CONFIG_USER_ONLY)
1489
F_OP(xto, q)
1490
{
1491
    set_float_exception_flags(0, &env->fp_status);
1492
    QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
1493
    check_ieee_exceptions();
1494
}
1495
#endif
1496
#endif
1497
#endif
1498
#undef F_HELPER
1499

    
1500
/* floating point conversion */
1501
void OPPROTO op_fdtos(void)
1502
{
1503
    set_float_exception_flags(0, &env->fp_status);
1504
    FT0 = float64_to_float32(DT1, &env->fp_status);
1505
    check_ieee_exceptions();
1506
}
1507

    
1508
void OPPROTO op_fstod(void)
1509
{
1510
    set_float_exception_flags(0, &env->fp_status);
1511
    DT0 = float32_to_float64(FT1, &env->fp_status);
1512
    check_ieee_exceptions();
1513
}
1514

    
1515
#if defined(CONFIG_USER_ONLY)
1516
void OPPROTO op_fqtos(void)
1517
{
1518
    set_float_exception_flags(0, &env->fp_status);
1519
    FT0 = float128_to_float32(QT1, &env->fp_status);
1520
    check_ieee_exceptions();
1521
}
1522

    
1523
void OPPROTO op_fstoq(void)
1524
{
1525
    set_float_exception_flags(0, &env->fp_status);
1526
    QT0 = float32_to_float128(FT1, &env->fp_status);
1527
    check_ieee_exceptions();
1528
}
1529

    
1530
void OPPROTO op_fqtod(void)
1531
{
1532
    set_float_exception_flags(0, &env->fp_status);
1533
    DT0 = float128_to_float64(QT1, &env->fp_status);
1534
    check_ieee_exceptions();
1535
}
1536

    
1537
void OPPROTO op_fdtoq(void)
1538
{
1539
    set_float_exception_flags(0, &env->fp_status);
1540
    QT0 = float64_to_float128(DT1, &env->fp_status);
1541
    check_ieee_exceptions();
1542
}
1543
#endif
1544

    
1545
/* Float to integer conversion.  */
1546
void OPPROTO op_fstoi(void)
1547
{
1548
    set_float_exception_flags(0, &env->fp_status);
1549
    *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status);
1550
    check_ieee_exceptions();
1551
}
1552

    
1553
void OPPROTO op_fdtoi(void)
1554
{
1555
    set_float_exception_flags(0, &env->fp_status);
1556
    *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
1557
    check_ieee_exceptions();
1558
}
1559

    
1560
#if defined(CONFIG_USER_ONLY)
1561
void OPPROTO op_fqtoi(void)
1562
{
1563
    set_float_exception_flags(0, &env->fp_status);
1564
    *((int32_t *)&FT0) = float128_to_int32_round_to_zero(QT1, &env->fp_status);
1565
    check_ieee_exceptions();
1566
}
1567
#endif
1568

    
1569
#ifdef TARGET_SPARC64
1570
void OPPROTO op_fstox(void)
1571
{
1572
    set_float_exception_flags(0, &env->fp_status);
1573
    *((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status);
1574
    check_ieee_exceptions();
1575
}
1576

    
1577
void OPPROTO op_fdtox(void)
1578
{
1579
    set_float_exception_flags(0, &env->fp_status);
1580
    *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
1581
    check_ieee_exceptions();
1582
}
1583

    
1584
#if defined(CONFIG_USER_ONLY)
1585
void OPPROTO op_fqtox(void)
1586
{
1587
    set_float_exception_flags(0, &env->fp_status);
1588
    *((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status);
1589
    check_ieee_exceptions();
1590
}
1591
#endif
1592

    
1593
void OPPROTO op_fmovs_cc(void)
1594
{
1595
    if (T2)
1596
        FT0 = FT1;
1597
}
1598

    
1599
void OPPROTO op_fmovd_cc(void)
1600
{
1601
    if (T2)
1602
        DT0 = DT1;
1603
}
1604

    
1605
#if defined(CONFIG_USER_ONLY)
1606
void OPPROTO op_fmovq_cc(void)
1607
{
1608
    if (T2)
1609
        QT0 = QT1;
1610
}
1611
#endif
1612

    
1613
void OPPROTO op_mov_cc(void)
1614
{
1615
    if (T2)
1616
        T0 = T1;
1617
}
1618

    
1619
void OPPROTO op_flushw(void)
1620
{
1621
    if (env->cansave != NWINDOWS - 2) {
1622
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
1623
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1624
                                    ((env->wstate & 0x7) << 2)));
1625
    }
1626
}
1627

    
1628
void OPPROTO op_saved(void)
1629
{
1630
    env->cansave++;
1631
    if (env->otherwin == 0)
1632
        env->canrestore--;
1633
    else
1634
        env->otherwin--;
1635
    FORCE_RET();
1636
}
1637

    
1638
void OPPROTO op_restored(void)
1639
{
1640
    env->canrestore++;
1641
    if (env->cleanwin < NWINDOWS - 1)
1642
        env->cleanwin++;
1643
    if (env->otherwin == 0)
1644
        env->cansave--;
1645
    else
1646
        env->otherwin--;
1647
    FORCE_RET();
1648
}
1649
#endif
1650

    
1651
#ifdef TARGET_SPARC64
1652
// This function uses non-native bit order
1653
#define GET_FIELD(X, FROM, TO)                                  \
1654
    ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
1655

    
1656
// This function uses the order in the manuals, i.e. bit 0 is 2^0
1657
#define GET_FIELD_SP(X, FROM, TO)               \
1658
    GET_FIELD(X, 63 - (TO), 63 - (FROM))
1659

    
1660
void OPPROTO op_array8()
1661
{
1662
    T0 = (GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1663
        (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1664
        (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1665
        (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1666
        (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1667
        (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12);
1668
}
1669

    
1670
void OPPROTO op_array16()
1671
{
1672
    T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1673
          (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1674
          (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1675
          (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1676
          (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1677
          (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 1;
1678
}
1679

    
1680
void OPPROTO op_array32()
1681
{
1682
    T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1683
          (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1684
          (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1685
          (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1686
          (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1687
          (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 2;
1688
}
1689

    
1690
void OPPROTO op_alignaddr()
1691
{
1692
    uint64_t tmp;
1693

    
1694
    tmp = T0 + T1;
1695
    env->gsr &= ~7ULL;
1696
    env->gsr |= tmp & 7ULL;
1697
    T0 = tmp & ~7ULL;
1698
}
1699

    
1700
void OPPROTO op_faligndata()
1701
{
1702
    uint64_t tmp;
1703

    
1704
    tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8);
1705
    tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
1706
    *((uint64_t *)&DT0) = tmp;
1707
}
1708

    
1709
void OPPROTO op_movl_FT0_0(void)
1710
{
1711
    *((uint32_t *)&FT0) = 0;
1712
}
1713

    
1714
void OPPROTO op_movl_DT0_0(void)
1715
{
1716
    *((uint64_t *)&DT0) = 0;
1717
}
1718

    
1719
void OPPROTO op_movl_FT0_1(void)
1720
{
1721
    *((uint32_t *)&FT0) = 0xffffffff;
1722
}
1723

    
1724
void OPPROTO op_movl_DT0_1(void)
1725
{
1726
    *((uint64_t *)&DT0) = 0xffffffffffffffffULL;
1727
}
1728

    
1729
void OPPROTO op_fnot(void)
1730
{
1731
    *(uint64_t *)&DT0 = ~*(uint64_t *)&DT1;
1732
}
1733

    
1734
void OPPROTO op_fnots(void)
1735
{
1736
    *(uint32_t *)&FT0 = ~*(uint32_t *)&FT1;
1737
}
1738

    
1739
void OPPROTO op_fnor(void)
1740
{
1741
    *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 | *(uint64_t *)&DT1);
1742
}
1743

    
1744
void OPPROTO op_fnors(void)
1745
{
1746
    *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 | *(uint32_t *)&FT1);
1747
}
1748

    
1749
void OPPROTO op_for(void)
1750
{
1751
    *(uint64_t *)&DT0 |= *(uint64_t *)&DT1;
1752
}
1753

    
1754
void OPPROTO op_fors(void)
1755
{
1756
    *(uint32_t *)&FT0 |= *(uint32_t *)&FT1;
1757
}
1758

    
1759
void OPPROTO op_fxor(void)
1760
{
1761
    *(uint64_t *)&DT0 ^= *(uint64_t *)&DT1;
1762
}
1763

    
1764
void OPPROTO op_fxors(void)
1765
{
1766
    *(uint32_t *)&FT0 ^= *(uint32_t *)&FT1;
1767
}
1768

    
1769
void OPPROTO op_fand(void)
1770
{
1771
    *(uint64_t *)&DT0 &= *(uint64_t *)&DT1;
1772
}
1773

    
1774
void OPPROTO op_fands(void)
1775
{
1776
    *(uint32_t *)&FT0 &= *(uint32_t *)&FT1;
1777
}
1778

    
1779
void OPPROTO op_fornot(void)
1780
{
1781
    *(uint64_t *)&DT0 = *(uint64_t *)&DT0 | ~*(uint64_t *)&DT1;
1782
}
1783

    
1784
void OPPROTO op_fornots(void)
1785
{
1786
    *(uint32_t *)&FT0 = *(uint32_t *)&FT0 | ~*(uint32_t *)&FT1;
1787
}
1788

    
1789
void OPPROTO op_fandnot(void)
1790
{
1791
    *(uint64_t *)&DT0 = *(uint64_t *)&DT0 & ~*(uint64_t *)&DT1;
1792
}
1793

    
1794
void OPPROTO op_fandnots(void)
1795
{
1796
    *(uint32_t *)&FT0 = *(uint32_t *)&FT0 & ~*(uint32_t *)&FT1;
1797
}
1798

    
1799
void OPPROTO op_fnand(void)
1800
{
1801
    *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 & *(uint64_t *)&DT1);
1802
}
1803

    
1804
void OPPROTO op_fnands(void)
1805
{
1806
    *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 & *(uint32_t *)&FT1);
1807
}
1808

    
1809
void OPPROTO op_fxnor(void)
1810
{
1811
    *(uint64_t *)&DT0 ^= ~*(uint64_t *)&DT1;
1812
}
1813

    
1814
void OPPROTO op_fxnors(void)
1815
{
1816
    *(uint32_t *)&FT0 ^= ~*(uint32_t *)&FT1;
1817
}
1818

    
1819
#ifdef WORDS_BIGENDIAN
1820
#define VIS_B64(n) b[7 - (n)]
1821
#define VIS_W64(n) w[3 - (n)]
1822
#define VIS_SW64(n) sw[3 - (n)]
1823
#define VIS_L64(n) l[1 - (n)]
1824
#define VIS_B32(n) b[3 - (n)]
1825
#define VIS_W32(n) w[1 - (n)]
1826
#else
1827
#define VIS_B64(n) b[n]
1828
#define VIS_W64(n) w[n]
1829
#define VIS_SW64(n) sw[n]
1830
#define VIS_L64(n) l[n]
1831
#define VIS_B32(n) b[n]
1832
#define VIS_W32(n) w[n]
1833
#endif
1834

    
1835
typedef union {
1836
    uint8_t b[8];
1837
    uint16_t w[4];
1838
    int16_t sw[4];
1839
    uint32_t l[2];
1840
    float64 d;
1841
} vis64;
1842

    
1843
typedef union {
1844
    uint8_t b[4];
1845
    uint16_t w[2];
1846
    uint32_t l;
1847
    float32 f;
1848
} vis32;
1849

    
1850
void OPPROTO op_fpmerge(void)
1851
{
1852
    vis64 s, d;
1853

    
1854
    s.d = DT0;
1855
    d.d = DT1;
1856

    
1857
    // Reverse calculation order to handle overlap
1858
    d.VIS_B64(7) = s.VIS_B64(3);
1859
    d.VIS_B64(6) = d.VIS_B64(3);
1860
    d.VIS_B64(5) = s.VIS_B64(2);
1861
    d.VIS_B64(4) = d.VIS_B64(2);
1862
    d.VIS_B64(3) = s.VIS_B64(1);
1863
    d.VIS_B64(2) = d.VIS_B64(1);
1864
    d.VIS_B64(1) = s.VIS_B64(0);
1865
    //d.VIS_B64(0) = d.VIS_B64(0);
1866

    
1867
    DT0 = d.d;
1868
}
1869

    
1870
void OPPROTO op_fmul8x16(void)
1871
{
1872
    vis64 s, d;
1873
    uint32_t tmp;
1874

    
1875
    s.d = DT0;
1876
    d.d = DT1;
1877

    
1878
#define PMUL(r)                                                 \
1879
    tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r);       \
1880
    if ((tmp & 0xff) > 0x7f)                                    \
1881
        tmp += 0x100;                                           \
1882
    d.VIS_W64(r) = tmp >> 8;
1883

    
1884
    PMUL(0);
1885
    PMUL(1);
1886
    PMUL(2);
1887
    PMUL(3);
1888
#undef PMUL
1889

    
1890
    DT0 = d.d;
1891
}
1892

    
1893
void OPPROTO op_fmul8x16al(void)
1894
{
1895
    vis64 s, d;
1896
    uint32_t tmp;
1897

    
1898
    s.d = DT0;
1899
    d.d = DT1;
1900

    
1901
#define PMUL(r)                                                 \
1902
    tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r);       \
1903
    if ((tmp & 0xff) > 0x7f)                                    \
1904
        tmp += 0x100;                                           \
1905
    d.VIS_W64(r) = tmp >> 8;
1906

    
1907
    PMUL(0);
1908
    PMUL(1);
1909
    PMUL(2);
1910
    PMUL(3);
1911
#undef PMUL
1912

    
1913
    DT0 = d.d;
1914
}
1915

    
1916
void OPPROTO op_fmul8x16au(void)
1917
{
1918
    vis64 s, d;
1919
    uint32_t tmp;
1920

    
1921
    s.d = DT0;
1922
    d.d = DT1;
1923

    
1924
#define PMUL(r)                                                 \
1925
    tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r);       \
1926
    if ((tmp & 0xff) > 0x7f)                                    \
1927
        tmp += 0x100;                                           \
1928
    d.VIS_W64(r) = tmp >> 8;
1929

    
1930
    PMUL(0);
1931
    PMUL(1);
1932
    PMUL(2);
1933
    PMUL(3);
1934
#undef PMUL
1935

    
1936
    DT0 = d.d;
1937
}
1938

    
1939
void OPPROTO op_fmul8sux16(void)
1940
{
1941
    vis64 s, d;
1942
    uint32_t tmp;
1943

    
1944
    s.d = DT0;
1945
    d.d = DT1;
1946

    
1947
#define PMUL(r)                                                         \
1948
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
1949
    if ((tmp & 0xff) > 0x7f)                                            \
1950
        tmp += 0x100;                                                   \
1951
    d.VIS_W64(r) = tmp >> 8;
1952

    
1953
    PMUL(0);
1954
    PMUL(1);
1955
    PMUL(2);
1956
    PMUL(3);
1957
#undef PMUL
1958

    
1959
    DT0 = d.d;
1960
}
1961

    
1962
void OPPROTO op_fmul8ulx16(void)
1963
{
1964
    vis64 s, d;
1965
    uint32_t tmp;
1966

    
1967
    s.d = DT0;
1968
    d.d = DT1;
1969

    
1970
#define PMUL(r)                                                         \
1971
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
1972
    if ((tmp & 0xff) > 0x7f)                                            \
1973
        tmp += 0x100;                                                   \
1974
    d.VIS_W64(r) = tmp >> 8;
1975

    
1976
    PMUL(0);
1977
    PMUL(1);
1978
    PMUL(2);
1979
    PMUL(3);
1980
#undef PMUL
1981

    
1982
    DT0 = d.d;
1983
}
1984

    
1985
void OPPROTO op_fmuld8sux16(void)
1986
{
1987
    vis64 s, d;
1988
    uint32_t tmp;
1989

    
1990
    s.d = DT0;
1991
    d.d = DT1;
1992

    
1993
#define PMUL(r)                                                         \
1994
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
1995
    if ((tmp & 0xff) > 0x7f)                                            \
1996
        tmp += 0x100;                                                   \
1997
    d.VIS_L64(r) = tmp;
1998

    
1999
    // Reverse calculation order to handle overlap
2000
    PMUL(1);
2001
    PMUL(0);
2002
#undef PMUL
2003

    
2004
    DT0 = d.d;
2005
}
2006

    
2007
void OPPROTO op_fmuld8ulx16(void)
2008
{
2009
    vis64 s, d;
2010
    uint32_t tmp;
2011

    
2012
    s.d = DT0;
2013
    d.d = DT1;
2014

    
2015
#define PMUL(r)                                                         \
2016
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
2017
    if ((tmp & 0xff) > 0x7f)                                            \
2018
        tmp += 0x100;                                                   \
2019
    d.VIS_L64(r) = tmp;
2020

    
2021
    // Reverse calculation order to handle overlap
2022
    PMUL(1);
2023
    PMUL(0);
2024
#undef PMUL
2025

    
2026
    DT0 = d.d;
2027
}
2028

    
2029
void OPPROTO op_fexpand(void)
2030
{
2031
    vis32 s;
2032
    vis64 d;
2033

    
2034
    s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff);
2035
    d.d = DT1;
2036
    d.VIS_L64(0) = s.VIS_W32(0) << 4;
2037
    d.VIS_L64(1) = s.VIS_W32(1) << 4;
2038
    d.VIS_L64(2) = s.VIS_W32(2) << 4;
2039
    d.VIS_L64(3) = s.VIS_W32(3) << 4;
2040

    
2041
    DT0 = d.d;
2042
}
2043

    
2044
#define VIS_OP(name, F)                                 \
2045
    void OPPROTO name##16(void)                         \
2046
    {                                                   \
2047
        vis64 s, d;                                     \
2048
                                                        \
2049
        s.d = DT0;                                      \
2050
        d.d = DT1;                                      \
2051
                                                        \
2052
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0));   \
2053
        d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1));   \
2054
        d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2));   \
2055
        d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3));   \
2056
                                                        \
2057
        DT0 = d.d;                                      \
2058
    }                                                   \
2059
                                                        \
2060
    void OPPROTO name##16s(void)                        \
2061
    {                                                   \
2062
        vis32 s, d;                                     \
2063
                                                        \
2064
        s.f = FT0;                                      \
2065
        d.f = FT1;                                      \
2066
                                                        \
2067
        d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0));   \
2068
        d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1));   \
2069
                                                        \
2070
        FT0 = d.f;                                      \
2071
    }                                                   \
2072
                                                        \
2073
    void OPPROTO name##32(void)                         \
2074
    {                                                   \
2075
        vis64 s, d;                                     \
2076
                                                        \
2077
        s.d = DT0;                                      \
2078
        d.d = DT1;                                      \
2079
                                                        \
2080
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0));   \
2081
        d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1));   \
2082
                                                        \
2083
        DT0 = d.d;                                      \
2084
    }                                                   \
2085
                                                        \
2086
    void OPPROTO name##32s(void)                        \
2087
    {                                                   \
2088
        vis32 s, d;                                     \
2089
                                                        \
2090
        s.f = FT0;                                      \
2091
        d.f = FT1;                                      \
2092
                                                        \
2093
        d.l = F(d.l, s.l);                              \
2094
                                                        \
2095
        FT0 = d.f;                                      \
2096
    }
2097

    
2098
#define FADD(a, b) ((a) + (b))
2099
#define FSUB(a, b) ((a) - (b))
2100
VIS_OP(op_fpadd, FADD)
2101
VIS_OP(op_fpsub, FSUB)
2102

    
2103
#define VIS_CMPOP(name, F)                                        \
2104
    void OPPROTO name##16(void)                                   \
2105
    {                                                             \
2106
        vis64 s, d;                                               \
2107
                                                                  \
2108
        s.d = DT0;                                                \
2109
        d.d = DT1;                                                \
2110
                                                                  \
2111
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0;       \
2112
        d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0;      \
2113
        d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0;      \
2114
        d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0;      \
2115
                                                                  \
2116
        DT0 = d.d;                                                \
2117
    }                                                             \
2118
                                                                  \
2119
    void OPPROTO name##32(void)                                   \
2120
    {                                                             \
2121
        vis64 s, d;                                               \
2122
                                                                  \
2123
        s.d = DT0;                                                \
2124
        d.d = DT1;                                                \
2125
                                                                  \
2126
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0;       \
2127
        d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0;      \
2128
                                                                  \
2129
        DT0 = d.d;                                                \
2130
    }
2131

    
2132
#define FCMPGT(a, b) ((a) > (b))
2133
#define FCMPEQ(a, b) ((a) == (b))
2134
#define FCMPLE(a, b) ((a) <= (b))
2135
#define FCMPNE(a, b) ((a) != (b))
2136

    
2137
VIS_CMPOP(op_fcmpgt, FCMPGT)
2138
VIS_CMPOP(op_fcmpeq, FCMPEQ)
2139
VIS_CMPOP(op_fcmple, FCMPLE)
2140
VIS_CMPOP(op_fcmpne, FCMPNE)
2141

    
2142
#endif
2143

    
2144
#define CHECK_ALIGN_OP(align)                           \
2145
    void OPPROTO op_check_align_T0_ ## align (void)     \
2146
    {                                                   \
2147
        if (T0 & align)                                 \
2148
            raise_exception(TT_UNALIGNED);              \
2149
        FORCE_RET();                                    \
2150
    }
2151

    
2152
CHECK_ALIGN_OP(1)
2153
CHECK_ALIGN_OP(3)
2154
CHECK_ALIGN_OP(7)