Revision f18cd223

b/target-alpha/cpu.h
277 277
     */
278 278
    target_ulong t0, t1;
279 279
#endif
280
    /* */
281
    double ft0, ft1, ft2;
282 280

  
283 281
    /* Those resources are used only in Qemu core */
284 282
    CPU_COMMON
b/target-alpha/exec.h
44 44

  
45 45
#define PARAM(n) ((uint64_t)PARAM##n)
46 46
#define SPARAM(n) ((int32_t)PARAM##n)
47
#define FT0 (env->ft0)
48
#define FT1 (env->ft1)
49
#define FT2 (env->ft2)
50 47
#define FP_STATUS (env->fp_status)
51 48

  
52 49
#if defined (DEBUG_OP)
b/target-alpha/helper.c
434 434
        if ((i % 3) == 2)
435 435
            cpu_fprintf(f, "\n");
436 436
    }
437
    cpu_fprintf(f, "FT " TARGET_FMT_lx " " TARGET_FMT_lx " " TARGET_FMT_lx,
438
                *((uint64_t *)(&env->ft0)), *((uint64_t *)(&env->ft1)),
439
                *((uint64_t *)(&env->ft2)));
440
    cpu_fprintf(f, "\nMEM " TARGET_FMT_lx " %d %d\n",
441
                ldq_raw(0x000000004007df60ULL),
442
                (uint8_t *)(&env->ft0), (uint8_t *)(&env->fir[0]));
443 437
}
444 438

  
445 439
void cpu_dump_EA (target_ulong EA)
b/target-alpha/helper.h
41 41
DEF_HELPER(uint64_t, helper_insqh, (int64_t, uint64_t))
42 42

  
43 43
DEF_HELPER(uint64_t, helper_cmpbge, (uint64_t, uint64_t))
44

  
45
DEF_HELPER(uint64_t, helper_load_fpcr, (void))
46
DEF_HELPER(void, helper_store_fpcr, (uint64_t val))
47

  
48
DEF_HELPER(uint32_t, helper_f_to_memory, (uint64_t s))
49
DEF_HELPER(uint64_t, helper_memory_to_f, (uint32_t s))
50
DEF_HELPER(uint64_t, helper_addf, (uint64_t, uint64_t))
51
DEF_HELPER(uint64_t, helper_subf, (uint64_t, uint64_t))
52
DEF_HELPER(uint64_t, helper_mulf, (uint64_t, uint64_t))
53
DEF_HELPER(uint64_t, helper_divf, (uint64_t, uint64_t))
54
DEF_HELPER(uint64_t, helper_sqrtf, (uint64_t))
55

  
56
DEF_HELPER(uint64_t, helper_g_to_memory, (uint64_t s))
57
DEF_HELPER(uint64_t, helper_memory_to_g, (uint64_t s))
58
DEF_HELPER(uint64_t, helper_addg, (uint64_t, uint64_t))
59
DEF_HELPER(uint64_t, helper_subg, (uint64_t, uint64_t))
60
DEF_HELPER(uint64_t, helper_mulg, (uint64_t, uint64_t))
61
DEF_HELPER(uint64_t, helper_divg, (uint64_t, uint64_t))
62
DEF_HELPER(uint64_t, helper_sqrtg, (uint64_t))
63

  
64
DEF_HELPER(uint32_t, helper_s_to_memory, (uint64_t s))
65
DEF_HELPER(uint64_t, helper_memory_to_s, (uint32_t s))
66
DEF_HELPER(uint64_t, helper_adds, (uint64_t, uint64_t))
67
DEF_HELPER(uint64_t, helper_subs, (uint64_t, uint64_t))
68
DEF_HELPER(uint64_t, helper_muls, (uint64_t, uint64_t))
69
DEF_HELPER(uint64_t, helper_divs, (uint64_t, uint64_t))
70
DEF_HELPER(uint64_t, helper_sqrts, (uint64_t))
71

  
72
DEF_HELPER(uint64_t, helper_addt, (uint64_t, uint64_t))
73
DEF_HELPER(uint64_t, helper_subt, (uint64_t, uint64_t))
74
DEF_HELPER(uint64_t, helper_mult, (uint64_t, uint64_t))
75
DEF_HELPER(uint64_t, helper_divt, (uint64_t, uint64_t))
76
DEF_HELPER(uint64_t, helper_sqrtt, (uint64_t))
77

  
78
DEF_HELPER(uint64_t, helper_cmptun, (uint64_t, uint64_t))
79
DEF_HELPER(uint64_t, helper_cmpteq, (uint64_t, uint64_t))
80
DEF_HELPER(uint64_t, helper_cmptle, (uint64_t, uint64_t))
81
DEF_HELPER(uint64_t, helper_cmptlt, (uint64_t, uint64_t))
82
DEF_HELPER(uint64_t, helper_cmpgeq, (uint64_t, uint64_t))
83
DEF_HELPER(uint64_t, helper_cmpgle, (uint64_t, uint64_t))
84
DEF_HELPER(uint64_t, helper_cmpglt, (uint64_t, uint64_t))
85

  
86
DEF_HELPER(uint64_t, helper_cmpfeq, (uint64_t))
87
DEF_HELPER(uint64_t, helper_cmpfne, (uint64_t))
88
DEF_HELPER(uint64_t, helper_cmpflt, (uint64_t))
89
DEF_HELPER(uint64_t, helper_cmpfle, (uint64_t))
90
DEF_HELPER(uint64_t, helper_cmpfgt, (uint64_t))
91
DEF_HELPER(uint64_t, helper_cmpfge, (uint64_t))
92

  
93
DEF_HELPER(uint64_t, helper_cpys, (uint64_t, uint64_t))
94
DEF_HELPER(uint64_t, helper_cpysn, (uint64_t, uint64_t))
95
DEF_HELPER(uint64_t, helper_cpyse, (uint64_t, uint64_t))
96

  
97
DEF_HELPER(uint64_t, helper_cvtts, (uint64_t))
98
DEF_HELPER(uint64_t, helper_cvtst, (uint64_t))
99
DEF_HELPER(uint64_t, helper_cvttq, (uint64_t))
100
DEF_HELPER(uint32_t, helper_cvtqs, (uint64_t))
101
DEF_HELPER(uint64_t, helper_cvtqt, (uint64_t))
102
DEF_HELPER(uint64_t, helper_cvtqf, (uint64_t))
103
DEF_HELPER(uint64_t, helper_cvtgf, (uint64_t))
104
DEF_HELPER(uint64_t, helper_cvtgq, (uint64_t))
105
DEF_HELPER(uint64_t, helper_cvtqg, (uint64_t))
106
DEF_HELPER(uint64_t, helper_cvtlq, (uint64_t))
107
DEF_HELPER(uint64_t, helper_cvtql, (uint64_t))
108
DEF_HELPER(uint64_t, helper_cvtqlv, (uint64_t))
109
DEF_HELPER(uint64_t, helper_cvtqlsv, (uint64_t))
110

  
b/target-alpha/op.c
23 23
#include "config.h"
24 24
#include "exec.h"
25 25
#include "host-utils.h"
26

  
27 26
#include "op_helper.h"
28 27

  
29
#define REG 0
30
#include "op_template.h"
31

  
32
#define REG 1
33
#include "op_template.h"
34

  
35
#define REG 2
36
#include "op_template.h"
37

  
38
#define REG 3
39
#include "op_template.h"
40

  
41
#define REG 4
42
#include "op_template.h"
43

  
44
#define REG 5
45
#include "op_template.h"
46

  
47
#define REG 6
48
#include "op_template.h"
49

  
50
#define REG 7
51
#include "op_template.h"
52

  
53
#define REG 8
54
#include "op_template.h"
55

  
56
#define REG 9
57
#include "op_template.h"
58

  
59
#define REG 10
60
#include "op_template.h"
61

  
62
#define REG 11
63
#include "op_template.h"
64

  
65
#define REG 12
66
#include "op_template.h"
67

  
68
#define REG 13
69
#include "op_template.h"
70

  
71
#define REG 14
72
#include "op_template.h"
73

  
74
#define REG 15
75
#include "op_template.h"
76

  
77
#define REG 16
78
#include "op_template.h"
79

  
80
#define REG 17
81
#include "op_template.h"
82

  
83
#define REG 18
84
#include "op_template.h"
85

  
86
#define REG 19
87
#include "op_template.h"
88

  
89
#define REG 20
90
#include "op_template.h"
91

  
92
#define REG 21
93
#include "op_template.h"
94

  
95
#define REG 22
96
#include "op_template.h"
97

  
98
#define REG 23
99
#include "op_template.h"
100

  
101
#define REG 24
102
#include "op_template.h"
103

  
104
#define REG 25
105
#include "op_template.h"
106

  
107
#define REG 26
108
#include "op_template.h"
109

  
110
#define REG 27
111
#include "op_template.h"
112

  
113
#define REG 28
114
#include "op_template.h"
115

  
116
#define REG 29
117
#include "op_template.h"
118

  
119
#define REG 30
120
#include "op_template.h"
121

  
122
#define REG 31
123
#include "op_template.h"
124

  
125 28
/* Debug stuff */
126 29
void OPPROTO op_no_op (void)
127 30
{
......
148 51
#include "op_mem.h"
149 52
#endif
150 53

  
151
/* Misc */
152
void OPPROTO op_load_fpcr (void)
153
{
154
    helper_load_fpcr();
155
    RETURN();
156
}
157

  
158
void OPPROTO op_store_fpcr (void)
159
{
160
    helper_store_fpcr();
161
    RETURN();
162
}
163

  
164
/* Tests */
165
#if 0 // Qemu does not know how to do this...
166
void OPPROTO op_bcond (void)
167
{
168
    if (T0)
169
        env->pc = T1 & ~3;
170
    else
171
        env->pc = PARAM(1);
172
    RETURN();
173
}
174
#else
175
void OPPROTO op_bcond (void)
176
{
177
    if (T0)
178
        env->pc = T1 & ~3;
179
    else
180
        env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
181
    RETURN();
182
}
183
#endif
184

  
185
/* IEEE floating point arithmetic */
186
/* S floating (single) */
187
void OPPROTO op_adds (void)
188
{
189
    FT0 = float32_add(FT0, FT1, &FP_STATUS);
190
    RETURN();
191
}
192

  
193
void OPPROTO op_subs (void)
194
{
195
    FT0 = float32_sub(FT0, FT1, &FP_STATUS);
196
    RETURN();
197
}
198

  
199
void OPPROTO op_muls (void)
200
{
201
    FT0 = float32_mul(FT0, FT1, &FP_STATUS);
202
    RETURN();
203
}
204

  
205
void OPPROTO op_divs (void)
206
{
207
    FT0 = float32_div(FT0, FT1, &FP_STATUS);
208
    RETURN();
209
}
210

  
211
void OPPROTO op_sqrts (void)
212
{
213
    helper_sqrts();
214
    RETURN();
215
}
216

  
217
void OPPROTO op_cpys (void)
218
{
219
    helper_cpys();
220
    RETURN();
221
}
222

  
223
void OPPROTO op_cpysn (void)
224
{
225
    helper_cpysn();
226
    RETURN();
227
}
228

  
229
void OPPROTO op_cpyse (void)
230
{
231
    helper_cpyse();
232
    RETURN();
233
}
234

  
235
void OPPROTO op_itofs (void)
236
{
237
    helper_itofs();
238
    RETURN();
239
}
240

  
241
void OPPROTO op_ftois (void)
242
{
243
    helper_ftois();
244
    RETURN();
245
}
246

  
247
/* T floating (double) */
248
void OPPROTO op_addt (void)
249
{
250
    FT0 = float64_add(FT0, FT1, &FP_STATUS);
251
    RETURN();
252
}
253

  
254
void OPPROTO op_subt (void)
255
{
256
    FT0 = float64_sub(FT0, FT1, &FP_STATUS);
257
    RETURN();
258
}
259

  
260
void OPPROTO op_mult (void)
261
{
262
    FT0 = float64_mul(FT0, FT1, &FP_STATUS);
263
    RETURN();
264
}
265

  
266
void OPPROTO op_divt (void)
267
{
268
    FT0 = float64_div(FT0, FT1, &FP_STATUS);
269
    RETURN();
270
}
271

  
272
void OPPROTO op_sqrtt (void)
273
{
274
    helper_sqrtt();
275
    RETURN();
276
}
277

  
278
void OPPROTO op_cmptun (void)
279
{
280
    helper_cmptun();
281
    RETURN();
282
}
283

  
284
void OPPROTO op_cmpteq (void)
285
{
286
    helper_cmpteq();
287
    RETURN();
288
}
289

  
290
void OPPROTO op_cmptle (void)
291
{
292
    helper_cmptle();
293
    RETURN();
294
}
295

  
296
void OPPROTO op_cmptlt (void)
297
{
298
    helper_cmptlt();
299
    RETURN();
300
}
301

  
302
void OPPROTO op_itoft (void)
303
{
304
    helper_itoft();
305
    RETURN();
306
}
307

  
308
void OPPROTO op_ftoit (void)
309
{
310
    helper_ftoit();
311
    RETURN();
312
}
313

  
314
/* VAX floating point arithmetic */
315
/* F floating */
316
void OPPROTO op_addf (void)
317
{
318
    helper_addf();
319
    RETURN();
320
}
321

  
322
void OPPROTO op_subf (void)
323
{
324
    helper_subf();
325
    RETURN();
326
}
327

  
328
void OPPROTO op_mulf (void)
329
{
330
    helper_mulf();
331
    RETURN();
332
}
333

  
334
void OPPROTO op_divf (void)
335
{
336
    helper_divf();
337
    RETURN();
338
}
339

  
340
void OPPROTO op_sqrtf (void)
341
{
342
    helper_sqrtf();
343
    RETURN();
344
}
345

  
346
void OPPROTO op_cmpfeq (void)
347
{
348
    helper_cmpfeq();
349
    RETURN();
350
}
351

  
352
void OPPROTO op_cmpfne (void)
353
{
354
    helper_cmpfne();
355
    RETURN();
356
}
357

  
358
void OPPROTO op_cmpflt (void)
359
{
360
    helper_cmpflt();
361
    RETURN();
362
}
363

  
364
void OPPROTO op_cmpfle (void)
365
{
366
    helper_cmpfle();
367
    RETURN();
368
}
369

  
370
void OPPROTO op_cmpfgt (void)
371
{
372
    helper_cmpfgt();
373
    RETURN();
374
}
375

  
376
void OPPROTO op_cmpfge (void)
377
{
378
    helper_cmpfge();
379
    RETURN();
380
}
381

  
382
void OPPROTO op_itoff (void)
383
{
384
    helper_itoff();
385
    RETURN();
386
}
387

  
388
/* G floating */
389
void OPPROTO op_addg (void)
390
{
391
    helper_addg();
392
    RETURN();
393
}
394

  
395
void OPPROTO op_subg (void)
396
{
397
    helper_subg();
398
    RETURN();
399
}
400

  
401
void OPPROTO op_mulg (void)
402
{
403
    helper_mulg();
404
    RETURN();
405
}
406

  
407
void OPPROTO op_divg (void)
408
{
409
    helper_divg();
410
    RETURN();
411
}
412

  
413
void OPPROTO op_sqrtg (void)
414
{
415
    helper_sqrtg();
416
    RETURN();
417
}
418

  
419
void OPPROTO op_cmpgeq (void)
420
{
421
    helper_cmpgeq();
422
    RETURN();
423
}
424

  
425
void OPPROTO op_cmpglt (void)
426
{
427
    helper_cmpglt();
428
    RETURN();
429
}
430

  
431
void OPPROTO op_cmpgle (void)
432
{
433
    helper_cmpgle();
434
    RETURN();
435
}
436

  
437
/* Floating point format conversion */
438
void OPPROTO op_cvtst (void)
439
{
440
    FT0 = (float)FT0;
441
    RETURN();
442
}
443

  
444
void OPPROTO op_cvtqs (void)
445
{
446
    helper_cvtqs();
447
    RETURN();
448
}
449

  
450
void OPPROTO op_cvtts (void)
451
{
452
    FT0 = (float)FT0;
453
    RETURN();
454
}
455

  
456
void OPPROTO op_cvttq (void)
457
{
458
    helper_cvttq();
459
    RETURN();
460
}
461

  
462
void OPPROTO op_cvtqt (void)
463
{
464
    helper_cvtqt();
465
    RETURN();
466
}
467

  
468
void OPPROTO op_cvtqf (void)
469
{
470
    helper_cvtqf();
471
    RETURN();
472
}
473

  
474
void OPPROTO op_cvtgf (void)
475
{
476
    helper_cvtgf();
477
    RETURN();
478
}
479

  
480
void OPPROTO op_cvtgd (void)
481
{
482
    helper_cvtgd();
483
    RETURN();
484
}
485

  
486
void OPPROTO op_cvtgq (void)
487
{
488
    helper_cvtgq();
489
    RETURN();
490
}
491

  
492
void OPPROTO op_cvtqg (void)
493
{
494
    helper_cvtqg();
495
    RETURN();
496
}
497

  
498
void OPPROTO op_cvtdg (void)
499
{
500
    helper_cvtdg();
501
    RETURN();
502
}
503

  
504
void OPPROTO op_cvtlq (void)
505
{
506
    helper_cvtlq();
507
    RETURN();
508
}
509

  
510
void OPPROTO op_cvtql (void)
511
{
512
    helper_cvtql();
513
    RETURN();
514
}
515

  
516
void OPPROTO op_cvtqlv (void)
517
{
518
    helper_cvtqlv();
519
    RETURN();
520
}
521

  
522
void OPPROTO op_cvtqlsv (void)
523
{
524
    helper_cvtqlsv();
525
    RETURN();
526
}
527

  
528 54
/* PALcode support special instructions */
529 55
#if !defined (CONFIG_USER_ONLY)
530 56
void OPPROTO op_hw_rei (void)
b/target-alpha/op_helper.c
24 24

  
25 25
#include "op_helper.h"
26 26

  
27
#define MEMSUFFIX _raw
28
#include "op_helper_mem.h"
29

  
30
#if !defined(CONFIG_USER_ONLY)
31
#define MEMSUFFIX _kernel
32
#include "op_helper_mem.h"
33

  
34
#define MEMSUFFIX _executive
35
#include "op_helper_mem.h"
36

  
37
#define MEMSUFFIX _supervisor
38
#include "op_helper_mem.h"
39

  
40
#define MEMSUFFIX _user
41
#include "op_helper_mem.h"
42

  
43
/* This is used for pal modes */
44
#define MEMSUFFIX _data
45
#include "op_helper_mem.h"
46
#endif
47

  
48 27
void helper_tb_flush (void)
49 28
{
50 29
    tlb_flush(env, 1);
......
91 70
    return env->implver;
92 71
}
93 72

  
94
void helper_load_fpcr (void)
73
uint64_t helper_load_fpcr (void)
95 74
{
96
    T0 = 0;
75
    uint64_t ret = 0;
97 76
#ifdef CONFIG_SOFTFLOAT
98
    T0 |= env->fp_status.float_exception_flags << 52;
77
    ret |= env->fp_status.float_exception_flags << 52;
99 78
    if (env->fp_status.float_exception_flags)
100
        T0 |= 1ULL << 63;
79
        ret |= 1ULL << 63;
101 80
    env->ipr[IPR_EXC_SUM] &= ~0x3E:
102 81
    env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1;
103 82
#endif
104 83
    switch (env->fp_status.float_rounding_mode) {
105 84
    case float_round_nearest_even:
106
        T0 |= 2ULL << 58;
85
        ret |= 2ULL << 58;
107 86
        break;
108 87
    case float_round_down:
109
        T0 |= 1ULL << 58;
88
        ret |= 1ULL << 58;
110 89
        break;
111 90
    case float_round_up:
112
        T0 |= 3ULL << 58;
91
        ret |= 3ULL << 58;
113 92
        break;
114 93
    case float_round_to_zero:
115 94
        break;
116 95
    }
96
    return ret;
117 97
}
118 98

  
119
void helper_store_fpcr (void)
99
void helper_store_fpcr (uint64_t val)
120 100
{
121 101
#ifdef CONFIG_SOFTFLOAT
122
    set_float_exception_flags((T0 >> 52) & 0x3F, &FP_STATUS);
102
    set_float_exception_flags((val >> 52) & 0x3F, &FP_STATUS);
123 103
#endif
124
    switch ((T0 >> 58) & 3) {
104
    switch ((val >> 58) & 3) {
125 105
    case 0:
126 106
        set_float_rounding_mode(float_round_to_zero, &FP_STATUS);
127 107
        break;
......
367 347
    return res;
368 348
}
369 349

  
370
void helper_cmov_fir (int freg)
350
/* Floating point helpers */
351

  
352
/* F floating (VAX) */
353
static always_inline uint64_t float32_to_f (float32 fa)
371 354
{
372
    if (FT0 != 0)
373
        env->fir[freg] = FT1;
355
    uint32_t a;
356
    uint64_t r, exp, mant, sig;
357

  
358
    a = *(uint32_t*)(&fa);
359
    sig = ((uint64_t)a & 0x80000000) << 32;
360
    exp = (a >> 23) & 0xff;
361
    mant = ((uint64_t)a & 0x007fffff) << 29;
362

  
363
    if (exp == 255) {
364
        /* NaN or infinity */
365
        r = 1; /* VAX dirty zero */
366
    } else if (exp == 0) {
367
        if (mant == 0) {
368
            /* Zero */
369
            r = 0;
370
        } else {
371
            /* Denormalized */
372
            r = sig | ((exp + 1) << 52) | mant;
373
        }
374
    } else {
375
        if (exp >= 253) {
376
            /* Overflow */
377
            r = 1; /* VAX dirty zero */
378
        } else {
379
            r = sig | ((exp + 2) << 52);
380
        }
381
    }
382

  
383
    return r;
374 384
}
375 385

  
376
void helper_sqrts (void)
386
static always_inline float32 f_to_float32 (uint64_t a)
377 387
{
378
    FT0 = float32_sqrt(FT0, &FP_STATUS);
388
    uint32_t r, exp, mant_sig;
389

  
390
    exp = ((a >> 55) & 0x80) | ((a >> 52) & 0x7f);
391
    mant_sig = ((a >> 32) & 0x80000000) | ((a >> 29) & 0x007fffff);
392

  
393
    if (unlikely(!exp && mant_sig)) {
394
        /* Reserved operands / Dirty zero */
395
        helper_excp(EXCP_OPCDEC, 0);
396
    }
397

  
398
    if (exp < 3) {
399
        /* Underflow */
400
        r = 0;
401
    } else {
402
        r = ((exp - 2) << 23) | mant_sig;
403
    }
404

  
405
    return *(float32*)(&a);
379 406
}
380 407

  
381
void helper_cpys (void)
408
uint32_t helper_f_to_memory (uint64_t a)
382 409
{
383
    union {
384
        double d;
385
        uint64_t i;
386
    } p, q, r;
410
    uint32_t r;
411
    r =  (a & 0x00001fffe0000000ull) >> 13;
412
    r |= (a & 0x07ffe00000000000ull) >> 45;
413
    r |= (a & 0xc000000000000000ull) >> 48;
414
    return r;
415
}
387 416

  
388
    p.d = FT0;
389
    q.d = FT1;
390
    r.i = p.i & 0x8000000000000000ULL;
391
    r.i |= q.i & ~0x8000000000000000ULL;
392
    FT0 = r.d;
417
uint64_t helper_memory_to_f (uint32_t a)
418
{
419
    uint64_t r;
420
    r =  ((uint64_t)(a & 0x0000c000)) << 48;
421
    r |= ((uint64_t)(a & 0x003fffff)) << 45;
422
    r |= ((uint64_t)(a & 0xffff0000)) << 13;
423
    if (!(a & 0x00004000))
424
        r |= 0x7ll << 59;
425
    return r;
393 426
}
394 427

  
395
void helper_cpysn (void)
428
uint64_t helper_addf (uint64_t a, uint64_t b)
396 429
{
397
    union {
398
        double d;
399
        uint64_t i;
400
    } p, q, r;
430
    float32 fa, fb, fr;
401 431

  
402
    p.d = FT0;
403
    q.d = FT1;
404
    r.i = (~p.i) & 0x8000000000000000ULL;
405
    r.i |= q.i & ~0x8000000000000000ULL;
406
    FT0 = r.d;
432
    fa = f_to_float32(a);
433
    fb = f_to_float32(b);
434
    fr = float32_add(fa, fb, &FP_STATUS);
435
    return float32_to_f(fr);
407 436
}
408 437

  
409
void helper_cpyse (void)
438
uint64_t helper_subf (uint64_t a, uint64_t b)
410 439
{
411
    union {
412
        double d;
413
        uint64_t i;
414
    } p, q, r;
440
    float32 fa, fb, fr;
415 441

  
416
    p.d = FT0;
417
    q.d = FT1;
418
    r.i = p.i & 0xFFF0000000000000ULL;
419
    r.i |= q.i & ~0xFFF0000000000000ULL;
420
    FT0 = r.d;
442
    fa = f_to_float32(a);
443
    fb = f_to_float32(b);
444
    fr = float32_sub(fa, fb, &FP_STATUS);
445
    return float32_to_f(fr);
421 446
}
422 447

  
423
void helper_itofs (void)
448
uint64_t helper_mulf (uint64_t a, uint64_t b)
424 449
{
425
    union {
426
        double d;
427
        uint64_t i;
428
    } p;
450
    float32 fa, fb, fr;
429 451

  
430
    p.d = FT0;
431
    FT0 = int64_to_float32(p.i, &FP_STATUS);
452
    fa = f_to_float32(a);
453
    fb = f_to_float32(b);
454
    fr = float32_mul(fa, fb, &FP_STATUS);
455
    return float32_to_f(fr);
432 456
}
433 457

  
434
void helper_ftois (void)
458
uint64_t helper_divf (uint64_t a, uint64_t b)
435 459
{
436
    union {
437
        double d;
438
        uint64_t i;
439
    } p;
460
    float32 fa, fb, fr;
440 461

  
441
    p.i = float32_to_int64(FT0, &FP_STATUS);
442
    FT0 = p.d;
462
    fa = f_to_float32(a);
463
    fb = f_to_float32(b);
464
    fr = float32_div(fa, fb, &FP_STATUS);
465
    return float32_to_f(fr);
443 466
}
444 467

  
445
void helper_sqrtt (void)
468
uint64_t helper_sqrtf (uint64_t t)
446 469
{
447
    FT0 = float64_sqrt(FT0, &FP_STATUS);
470
    float32 ft, fr;
471

  
472
    ft = f_to_float32(t);
473
    fr = float32_sqrt(ft, &FP_STATUS);
474
    return float32_to_f(fr);
448 475
}
449 476

  
450
void helper_cmptun (void)
477

  
478
/* G floating (VAX) */
479
static always_inline uint64_t float64_to_g (float64 fa)
451 480
{
452
    union {
453
        double d;
454
        uint64_t i;
455
    } p;
481
    uint64_t a, r, exp, mant, sig;
456 482

  
457
    p.i = 0;
458
    if (float64_is_nan(FT0) || float64_is_nan(FT1))
459
        p.i = 0x4000000000000000ULL;
460
    FT0 = p.d;
483
    a = *(uint64_t*)(&fa);
484
    sig = a & 0x8000000000000000ull;
485
    exp = (a >> 52) & 0x7ff;
486
    mant = a & 0x000fffffffffffffull;
487

  
488
    if (exp == 2047) {
489
        /* NaN or infinity */
490
        r = 1; /* VAX dirty zero */
491
    } else if (exp == 0) {
492
        if (mant == 0) {
493
            /* Zero */
494
            r = 0;
495
        } else {
496
            /* Denormalized */
497
            r = sig | ((exp + 1) << 52) | mant;
498
        }
499
    } else {
500
        if (exp >= 2045) {
501
            /* Overflow */
502
            r = 1; /* VAX dirty zero */
503
        } else {
504
            r = sig | ((exp + 2) << 52);
505
        }
506
    }
507

  
508
    return r;
461 509
}
462 510

  
463
void helper_cmpteq (void)
511
static always_inline float64 g_to_float64 (uint64_t a)
464 512
{
465
    union {
466
        double d;
467
        uint64_t i;
468
    } p;
513
    uint64_t r, exp, mant_sig;
514

  
515
    exp = (a >> 52) & 0x7ff;
516
    mant_sig = a & 0x800fffffffffffffull;
517

  
518
    if (!exp && mant_sig) {
519
        /* Reserved operands / Dirty zero */
520
        helper_excp(EXCP_OPCDEC, 0);
521
    }
469 522

  
470
    p.i = 0;
471
    if (float64_eq(FT0, FT1, &FP_STATUS))
472
        p.i = 0x4000000000000000ULL;
473
    FT0 = p.d;
523
    if (exp < 3) {
524
        /* Underflow */
525
        r = 0;
526
    } else {
527
        r = ((exp - 2) << 52) | mant_sig;
528
    }
529

  
530
    return *(float64*)(&a);
474 531
}
475 532

  
476
void helper_cmptle (void)
533
uint64_t helper_g_to_memory (uint64_t a)
477 534
{
478
    union {
479
        double d;
480
        uint64_t i;
481
    } p;
535
    uint64_t r;
536
    r =  (a & 0x000000000000ffffull) << 48;
537
    r |= (a & 0x00000000ffff0000ull) << 16;
538
    r |= (a & 0x0000ffff00000000ull) >> 16;
539
    r |= (a & 0xffff000000000000ull) >> 48;
540
    return r;
541
}
482 542

  
483
    p.i = 0;
484
    if (float64_le(FT0, FT1, &FP_STATUS))
485
        p.i = 0x4000000000000000ULL;
486
    FT0 = p.d;
543
uint64_t helper_memory_to_g (uint64_t a)
544
{
545
    uint64_t r;
546
    r =  (a & 0x000000000000ffffull) << 48;
547
    r |= (a & 0x00000000ffff0000ull) << 16;
548
    r |= (a & 0x0000ffff00000000ull) >> 16;
549
    r |= (a & 0xffff000000000000ull) >> 48;
550
    return r;
487 551
}
488 552

  
489
void helper_cmptlt (void)
553
uint64_t helper_addg (uint64_t a, uint64_t b)
490 554
{
491
    union {
492
        double d;
493
        uint64_t i;
494
    } p;
555
    float64 fa, fb, fr;
495 556

  
496
    p.i = 0;
497
    if (float64_lt(FT0, FT1, &FP_STATUS))
498
        p.i = 0x4000000000000000ULL;
499
    FT0 = p.d;
557
    fa = g_to_float64(a);
558
    fb = g_to_float64(b);
559
    fr = float64_add(fa, fb, &FP_STATUS);
560
    return float64_to_g(fr);
500 561
}
501 562

  
502
void helper_itoft (void)
563
uint64_t helper_subg (uint64_t a, uint64_t b)
503 564
{
504
    union {
505
        double d;
506
        uint64_t i;
507
    } p;
565
    float64 fa, fb, fr;
508 566

  
509
    p.d = FT0;
510
    FT0 = int64_to_float64(p.i, &FP_STATUS);
567
    fa = g_to_float64(a);
568
    fb = g_to_float64(b);
569
    fr = float64_sub(fa, fb, &FP_STATUS);
570
    return float64_to_g(fr);
511 571
}
512 572

  
513
void helper_ftoit (void)
573
uint64_t helper_mulg (uint64_t a, uint64_t b)
514 574
{
515
    union {
516
        double d;
517
        uint64_t i;
518
    } p;
575
    float64 fa, fb, fr;
519 576

  
520
    p.i = float64_to_int64(FT0, &FP_STATUS);
521
    FT0 = p.d;
577
    fa = g_to_float64(a);
578
    fb = g_to_float64(b);
579
    fr = float64_mul(fa, fb, &FP_STATUS);
580
    return float64_to_g(fr);
522 581
}
523 582

  
524
static always_inline int vaxf_is_valid (float ff)
583
uint64_t helper_divg (uint64_t a, uint64_t b)
525 584
{
526
    union {
527
        float f;
528
        uint32_t i;
529
    } p;
530
    uint32_t exp, mant;
585
    float64 fa, fb, fr;
531 586

  
532
    p.f = ff;
533
    exp = (p.i >> 23) & 0xFF;
534
    mant = p.i & 0x007FFFFF;
535
    if (exp == 0 && ((p.i & 0x80000000) || mant != 0)) {
536
        /* Reserved operands / Dirty zero */
537
        return 0;
538
    }
587
    fa = g_to_float64(a);
588
    fb = g_to_float64(b);
589
    fr = float64_div(fa, fb, &FP_STATUS);
590
    return float64_to_g(fr);
591
}
592

  
593
uint64_t helper_sqrtg (uint64_t a)
594
{
595
    float64 fa, fr;
539 596

  
540
    return 1;
597
    fa = g_to_float64(a);
598
    fr = float64_sqrt(fa, &FP_STATUS);
599
    return float64_to_g(fr);
541 600
}
542 601

  
543
static always_inline float vaxf_to_ieee32 (float ff)
602

  
603
/* S floating (single) */
604
static always_inline uint64_t float32_to_s (float32 fa)
544 605
{
545
    union {
546
        float f;
547
        uint32_t i;
548
    } p;
549
    uint32_t exp;
606
    uint32_t a;
607
    uint64_t r;
550 608

  
551
    p.f = ff;
552
    exp = (p.i >> 23) & 0xFF;
553
    if (exp < 3) {
554
        /* Underflow */
555
        p.f = 0.0;
556
    } else {
557
        p.f *= 0.25;
558
    }
609
    a = *(uint32_t*)(&fa);
559 610

  
560
    return p.f;
611
    r = (((uint64_t)(a & 0xc0000000)) << 32) | (((uint64_t)(a & 0x3fffffff)) << 29);
612
    if (((a & 0x7f800000) != 0x7f800000) && (!(a & 0x40000000)))
613
        r |= 0x7ll << 59;
614
    return r;
561 615
}
562 616

  
563
static always_inline float ieee32_to_vaxf (float fi)
617
static always_inline float32 s_to_float32 (uint64_t a)
564 618
{
565
    union {
566
        float f;
567
        uint32_t i;
568
    } p;
569
    uint32_t exp, mant;
619
    uint32_t r = ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff);
620
    return *(float32*)(&r);
621
}
570 622

  
571
    p.f = fi;
572
    exp = (p.i >> 23) & 0xFF;
573
    mant = p.i & 0x007FFFFF;
574
    if (exp == 255) {
575
        /* NaN or infinity */
576
        p.i = 1;
577
    } else if (exp == 0) {
578
        if (mant == 0) {
579
            /* Zero */
580
            p.i = 0;
581
        } else {
582
            /* Denormalized */
583
            p.f *= 2.0;
584
        }
585
    } else {
586
        if (exp >= 253) {
587
            /* Overflow */
588
            p.i = 1;
589
        } else {
590
            p.f *= 4.0;
591
        }
592
    }
623
uint32_t helper_s_to_memory (uint64_t a)
624
{
625
    /* Memory format is the same as float32 */
626
    float32 fa = s_to_float32(a);
627
    return *(uint32_t*)(&fa);
628
}
593 629

  
594
    return p.f;
630
uint64_t helper_memory_to_s (uint32_t a)
631
{
632
    /* Memory format is the same as float32 */
633
    return float32_to_s(*(float32*)(&a));
595 634
}
596 635

  
597
void helper_addf (void)
636
uint64_t helper_adds (uint64_t a, uint64_t b)
598 637
{
599
    float ft0, ft1, ft2;
638
    float32 fa, fb, fr;
600 639

  
601
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
602
        /* XXX: TODO */
603
    }
604
    ft0 = vaxf_to_ieee32(FT0);
605
    ft1 = vaxf_to_ieee32(FT1);
606
    ft2 = float32_add(ft0, ft1, &FP_STATUS);
607
    FT0 = ieee32_to_vaxf(ft2);
640
    fa = s_to_float32(a);
641
    fb = s_to_float32(b);
642
    fr = float32_add(fa, fb, &FP_STATUS);
643
    return float32_to_s(fr);
608 644
}
609 645

  
610
void helper_subf (void)
646
uint64_t helper_subs (uint64_t a, uint64_t b)
611 647
{
612
    float ft0, ft1, ft2;
648
    float32 fa, fb, fr;
613 649

  
614
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
615
        /* XXX: TODO */
616
    }
617
    ft0 = vaxf_to_ieee32(FT0);
618
    ft1 = vaxf_to_ieee32(FT1);
619
    ft2 = float32_sub(ft0, ft1, &FP_STATUS);
620
    FT0 = ieee32_to_vaxf(ft2);
650
    fa = s_to_float32(a);
651
    fb = s_to_float32(b);
652
    fr = float32_sub(fa, fb, &FP_STATUS);
653
    return float32_to_s(fr);
621 654
}
622 655

  
623
void helper_mulf (void)
656
uint64_t helper_muls (uint64_t a, uint64_t b)
624 657
{
625
    float ft0, ft1, ft2;
658
    float32 fa, fb, fr;
626 659

  
627
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
628
        /* XXX: TODO */
629
    }
630
    ft0 = vaxf_to_ieee32(FT0);
631
    ft1 = vaxf_to_ieee32(FT1);
632
    ft2 = float32_mul(ft0, ft1, &FP_STATUS);
633
    FT0 = ieee32_to_vaxf(ft2);
660
    fa = s_to_float32(a);
661
    fb = s_to_float32(b);
662
    fr = float32_mul(fa, fb, &FP_STATUS);
663
    return float32_to_s(fr);
634 664
}
635 665

  
636
void helper_divf (void)
666
uint64_t helper_divs (uint64_t a, uint64_t b)
637 667
{
638
    float ft0, ft1, ft2;
668
    float32 fa, fb, fr;
639 669

  
640
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
641
        /* XXX: TODO */
642
    }
643
    ft0 = vaxf_to_ieee32(FT0);
644
    ft1 = vaxf_to_ieee32(FT1);
645
    ft2 = float32_div(ft0, ft1, &FP_STATUS);
646
    FT0 = ieee32_to_vaxf(ft2);
670
    fa = s_to_float32(a);
671
    fb = s_to_float32(b);
672
    fr = float32_div(fa, fb, &FP_STATUS);
673
    return float32_to_s(fr);
647 674
}
648 675

  
649
void helper_sqrtf (void)
676
uint64_t helper_sqrts (uint64_t a)
650 677
{
651
    float ft0, ft1;
678
    float32 fa, fr;
652 679

  
653
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
654
        /* XXX: TODO */
655
    }
656
    ft0 = vaxf_to_ieee32(FT0);
657
    ft1 = float32_sqrt(ft0, &FP_STATUS);
658
    FT0 = ieee32_to_vaxf(ft1);
680
    fa = s_to_float32(a);
681
    fr = float32_sqrt(fa, &FP_STATUS);
682
    return float32_to_s(fr);
659 683
}
660 684

  
661
void helper_itoff (void)
685

  
686
/* T floating (double) */
687
static always_inline float64 t_to_float64 (uint64_t a)
662 688
{
663
    /* XXX: TODO */
689
    /* Memory format is the same as float64 */
690
    return *(float64*)(&a);
664 691
}
665 692

  
666
static always_inline int vaxg_is_valid (double ff)
693
static always_inline uint64_t float64_to_t (float64 fa)
667 694
{
668
    union {
669
        double f;
670
        uint64_t i;
671
    } p;
672
    uint64_t exp, mant;
695
    /* Memory format is the same as float64 */
696
    return *(uint64*)(&fa);
697
}
673 698

  
674
    p.f = ff;
675
    exp = (p.i >> 52) & 0x7FF;
676
    mant = p.i & 0x000FFFFFFFFFFFFFULL;
677
    if (exp == 0 && ((p.i & 0x8000000000000000ULL) || mant != 0)) {
678
        /* Reserved operands / Dirty zero */
679
        return 0;
680
    }
699
uint64_t helper_addt (uint64_t a, uint64_t b)
700
{
701
    float64 fa, fb, fr;
681 702

  
682
    return 1;
703
    fa = t_to_float64(a);
704
    fb = t_to_float64(b);
705
    fr = float64_add(fa, fb, &FP_STATUS);
706
    return float64_to_t(fr);
683 707
}
684 708

  
685
static always_inline double vaxg_to_ieee64 (double fg)
709
uint64_t helper_subt (uint64_t a, uint64_t b)
686 710
{
687
    union {
688
        double f;
689
        uint64_t i;
690
    } p;
691
    uint32_t exp;
711
    float64 fa, fb, fr;
692 712

  
693
    p.f = fg;
694
    exp = (p.i >> 52) & 0x7FF;
695
    if (exp < 3) {
696
        /* Underflow */
697
        p.f = 0.0;
698
    } else {
699
        p.f *= 0.25;
700
    }
701

  
702
    return p.f;
713
    fa = t_to_float64(a);
714
    fb = t_to_float64(b);
715
    fr = float64_sub(fa, fb, &FP_STATUS);
716
    return float64_to_t(fr);
703 717
}
704 718

  
705
static always_inline double ieee64_to_vaxg (double fi)
719
uint64_t helper_mult (uint64_t a, uint64_t b)
706 720
{
707
    union {
708
        double f;
709
        uint64_t i;
710
    } p;
711
    uint64_t mant;
712
    uint32_t exp;
713

  
714
    p.f = fi;
715
    exp = (p.i >> 52) & 0x7FF;
716
    mant = p.i & 0x000FFFFFFFFFFFFFULL;
717
    if (exp == 255) {
718
        /* NaN or infinity */
719
        p.i = 1; /* VAX dirty zero */
720
    } else if (exp == 0) {
721
        if (mant == 0) {
722
            /* Zero */
723
            p.i = 0;
724
        } else {
725
            /* Denormalized */
726
            p.f *= 2.0;
727
        }
728
    } else {
729
        if (exp >= 2045) {
730
            /* Overflow */
731
            p.i = 1; /* VAX dirty zero */
732
        } else {
733
            p.f *= 4.0;
734
        }
735
    }
721
    float64 fa, fb, fr;
736 722

  
737
    return p.f;
723
    fa = t_to_float64(a);
724
    fb = t_to_float64(b);
725
    fr = float64_mul(fa, fb, &FP_STATUS);
726
    return float64_to_t(fr);
738 727
}
739 728

  
740
void helper_addg (void)
729
uint64_t helper_divt (uint64_t a, uint64_t b)
741 730
{
742
    double ft0, ft1, ft2;
731
    float64 fa, fb, fr;
743 732

  
744
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
745
        /* XXX: TODO */
746
    }
747
    ft0 = vaxg_to_ieee64(FT0);
748
    ft1 = vaxg_to_ieee64(FT1);
749
    ft2 = float64_add(ft0, ft1, &FP_STATUS);
750
    FT0 = ieee64_to_vaxg(ft2);
733
    fa = t_to_float64(a);
734
    fb = t_to_float64(b);
735
    fr = float64_div(fa, fb, &FP_STATUS);
736
    return float64_to_t(fr);
751 737
}
752 738

  
753
void helper_subg (void)
739
uint64_t helper_sqrtt (uint64_t a)
754 740
{
755
    double ft0, ft1, ft2;
741
    float64 fa, fr;
756 742

  
757
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
758
        /* XXX: TODO */
759
    }
760
    ft0 = vaxg_to_ieee64(FT0);
761
    ft1 = vaxg_to_ieee64(FT1);
762
    ft2 = float64_sub(ft0, ft1, &FP_STATUS);
763
    FT0 = ieee64_to_vaxg(ft2);
743
    fa = t_to_float64(a);
744
    fr = float64_sqrt(fa, &FP_STATUS);
745
    return float64_to_t(fr);
764 746
}
765 747

  
766
void helper_mulg (void)
767
{
768
    double ft0, ft1, ft2;
769 748

  
770
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
771
        /* XXX: TODO */
772
    }
773
    ft0 = vaxg_to_ieee64(FT0);
774
    ft1 = vaxg_to_ieee64(FT1);
775
    ft2 = float64_mul(ft0, ft1, &FP_STATUS);
776
    FT0 = ieee64_to_vaxg(ft2);
749
/* Sign copy */
750
uint64_t helper_cpys(uint64_t a, uint64_t b)
751
{
752
    return (a & 0x8000000000000000ULL) | (b & ~0x8000000000000000ULL);
777 753
}
778 754

  
779
void helper_divg (void)
755
uint64_t helper_cpysn(uint64_t a, uint64_t b)
780 756
{
781
    double ft0, ft1, ft2;
757
    return ((~a) & 0x8000000000000000ULL) | (b & ~0x8000000000000000ULL);
758
}
782 759

  
783
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
784
        /* XXX: TODO */
785
    }
786
    ft0 = vaxg_to_ieee64(FT0);
787
    ft1 = vaxg_to_ieee64(FT1);
788
    ft2 = float64_div(ft0, ft1, &FP_STATUS);
789
    FT0 = ieee64_to_vaxg(ft2);
760
uint64_t helper_cpyse(uint64_t a, uint64_t b)
761
{
762
    return (a & 0xFFF0000000000000ULL) | (b & ~0xFFF0000000000000ULL);
790 763
}
791 764

  
792
void helper_sqrtg (void)
765

  
766
/* Comparisons */
767
uint64_t helper_cmptun (uint64_t a, uint64_t b)
793 768
{
794
    double ft0, ft1;
769
    float64 fa, fb;
795 770

  
796
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
797
        /* XXX: TODO */
798
    }
799
    ft0 = vaxg_to_ieee64(FT0);
800
    ft1 = float64_sqrt(ft0, &FP_STATUS);
801
    FT0 = ieee64_to_vaxg(ft1);
771
    fa = t_to_float64(a);
772
    fb = t_to_float64(b);
773

  
774
    if (float64_is_nan(fa) || float64_is_nan(fb))
775
        return 0x4000000000000000ULL;
776
    else
777
        return 0;
802 778
}
803 779

  
804
void helper_cmpgeq (void)
780
uint64_t helper_cmpteq(uint64_t a, uint64_t b)
805 781
{
806
    union {
807
        double d;
808
        uint64_t u;
809
    } p;
810
    double ft0, ft1;
782
    float64 fa, fb;
811 783

  
812
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
813
        /* XXX: TODO */
814
    }
815
    ft0 = vaxg_to_ieee64(FT0);
816
    ft1 = vaxg_to_ieee64(FT1);
817
    p.u = 0;
818
    if (float64_eq(ft0, ft1, &FP_STATUS))
819
        p.u = 0x4000000000000000ULL;
820
    FT0 = p.d;
784
    fa = t_to_float64(a);
785
    fb = t_to_float64(b);
786

  
787
    if (float64_eq(fa, fb, &FP_STATUS))
788
        return 0x4000000000000000ULL;
789
    else
790
        return 0;
821 791
}
822 792

  
823
void helper_cmpglt (void)
793
uint64_t helper_cmptle(uint64_t a, uint64_t b)
824 794
{
825
    union {
826
        double d;
827
        uint64_t u;
828
    } p;
829
    double ft0, ft1;
795
    float64 fa, fb;
830 796

  
831
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
832
        /* XXX: TODO */
833
    }
834
    ft0 = vaxg_to_ieee64(FT0);
835
    ft1 = vaxg_to_ieee64(FT1);
836
    p.u = 0;
837
    if (float64_lt(ft0, ft1, &FP_STATUS))
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff