Revision dbb30fe6

b/target-alpha/helper.h
77 77
DEF_HELPER_2(cmpgle, i64, i64, i64)
78 78
DEF_HELPER_2(cmpglt, i64, i64, i64)
79 79

  
80
DEF_HELPER_1(cmpfeq, i64, i64)
81
DEF_HELPER_1(cmpfne, i64, i64)
82
DEF_HELPER_1(cmpflt, i64, i64)
83
DEF_HELPER_1(cmpfle, i64, i64)
84
DEF_HELPER_1(cmpfgt, i64, i64)
85
DEF_HELPER_1(cmpfge, i64, i64)
86

  
87 80
DEF_HELPER_2(cpys, i64, i64, i64)
88 81
DEF_HELPER_2(cpysn, i64, i64, i64)
89 82
DEF_HELPER_2(cpyse, i64, i64, i64)
b/target-alpha/op_helper.c
884 884
        return 0;
885 885
}
886 886

  
887
uint64_t helper_cmpfeq (uint64_t a)
888
{
889
    return !(a & 0x7FFFFFFFFFFFFFFFULL);
890
}
891

  
892
uint64_t helper_cmpfne (uint64_t a)
893
{
894
    return (a & 0x7FFFFFFFFFFFFFFFULL);
895
}
896

  
897
uint64_t helper_cmpflt (uint64_t a)
898
{
899
    return (a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL);
900
}
901

  
902
uint64_t helper_cmpfle (uint64_t a)
903
{
904
    return (a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL);
905
}
906

  
907
uint64_t helper_cmpfgt (uint64_t a)
908
{
909
    return !(a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL);
910
}
911

  
912
uint64_t helper_cmpfge (uint64_t a)
913
{
914
    return !(a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL);
915
}
916

  
917

  
918 887
/* Floating point format conversion */
919 888
uint64_t helper_cvtts (uint64_t a)
920 889
{
b/target-alpha/translate.c
294 294
    tcg_temp_free(addr);
295 295
}
296 296

  
297
static inline void gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
298
                             int32_t disp, int mask)
297
static void gen_bcond_pcload(DisasContext *ctx, int32_t disp, int lab_true)
299 298
{
300
    int l1, l2;
299
    int lab_over = gen_new_label();
300

  
301
    tcg_gen_movi_i64(cpu_pc, ctx->pc);
302
    tcg_gen_br(lab_over);
303
    gen_set_label(lab_true);
304
    tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
305
    gen_set_label(lab_over);
306
}
307

  
308
static void gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
309
                      int32_t disp, int mask)
310
{
311
    int lab_true = gen_new_label();
301 312

  
302
    l1 = gen_new_label();
303
    l2 = gen_new_label();
304 313
    if (likely(ra != 31)) {
305 314
        if (mask) {
306 315
            TCGv tmp = tcg_temp_new();
307 316
            tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
308
            tcg_gen_brcondi_i64(cond, tmp, 0, l1);
317
            tcg_gen_brcondi_i64(cond, tmp, 0, lab_true);
309 318
            tcg_temp_free(tmp);
310
        } else
311
            tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, l1);
319
        } else {
320
            tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, lab_true);
321
        }
312 322
    } else {
313 323
        /* Very uncommon case - Do not bother to optimize.  */
314 324
        TCGv tmp = tcg_const_i64(0);
315
        tcg_gen_brcondi_i64(cond, tmp, 0, l1);
325
        tcg_gen_brcondi_i64(cond, tmp, 0, lab_true);
316 326
        tcg_temp_free(tmp);
317 327
    }
318
    tcg_gen_movi_i64(cpu_pc, ctx->pc);
319
    tcg_gen_br(l2);
320
    gen_set_label(l1);
321
    tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
322
    gen_set_label(l2);
328
    gen_bcond_pcload(ctx, disp, lab_true);
323 329
}
324 330

  
325
static inline void gen_fbcond(DisasContext *ctx, int opc, int ra, int32_t disp)
331
/* Generate a forward TCG branch to LAB_TRUE if RA cmp 0.0.
332
   This is complicated by the fact that -0.0 compares the same as +0.0.  */
333

  
334
static void gen_fbcond_internal(TCGCond cond, TCGv src, int lab_true)
326 335
{
327
    int l1, l2;
336
    int lab_false = -1;
337
    uint64_t mzero = 1ull << 63;
328 338
    TCGv tmp;
329
    TCGv src;
330 339

  
331
    l1 = gen_new_label();
332
    l2 = gen_new_label();
333
    if (ra != 31) {
334
        tmp = tcg_temp_new();
335
        src = cpu_fir[ra];
336
    } else  {
337
        tmp = tcg_const_i64(0);
338
        src = tmp;
339
    }
340
    switch (opc) {
341
    case 0x31: /* FBEQ */
342
        gen_helper_cmpfeq(tmp, src);
343
        break;
344
    case 0x32: /* FBLT */
345
        gen_helper_cmpflt(tmp, src);
346
        break;
347
    case 0x33: /* FBLE */
348
        gen_helper_cmpfle(tmp, src);
340
    switch (cond) {
341
    case TCG_COND_LE:
342
    case TCG_COND_GT:
343
        /* For <= or >, the -0.0 value directly compares the way we want.  */
344
        tcg_gen_brcondi_i64(cond, src, 0, lab_true);
349 345
        break;
350
    case 0x35: /* FBNE */
351
        gen_helper_cmpfne(tmp, src);
346

  
347
    case TCG_COND_EQ:
348
    case TCG_COND_NE:
349
        /* For == or !=, we can simply mask off the sign bit and compare.  */
350
        /* ??? Assume that the temporary is reclaimed at the branch.  */
351
        tmp = tcg_temp_new();
352
        tcg_gen_andi_i64(tmp, src, mzero - 1);
353
        tcg_gen_brcondi_i64(cond, tmp, 0, lab_true);
352 354
        break;
353
    case 0x36: /* FBGE */
354
        gen_helper_cmpfge(tmp, src);
355

  
356
    case TCG_COND_GE:
357
        /* For >=, emit two branches to the destination.  */
358
        tcg_gen_brcondi_i64(cond, src, 0, lab_true);
359
        tcg_gen_brcondi_i64(TCG_COND_EQ, src, mzero, lab_true);
355 360
        break;
356
    case 0x37: /* FBGT */
357
        gen_helper_cmpfgt(tmp, src);
361

  
362
    case TCG_COND_LT:
363
        /* For <, first filter out -0.0 to what will be the fallthru.  */
364
        lab_false = gen_new_label();
365
        tcg_gen_brcondi_i64(TCG_COND_EQ, src, mzero, lab_false);
366
        tcg_gen_brcondi_i64(cond, src, 0, lab_true);
367
        gen_set_label(lab_false);
358 368
        break;
369

  
359 370
    default:
360 371
        abort();
361 372
    }
362
    tcg_gen_brcondi_i64(TCG_COND_NE, tmp, 0, l1);
363
    tcg_gen_movi_i64(cpu_pc, ctx->pc);
364
    tcg_gen_br(l2);
365
    gen_set_label(l1);
366
    tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
367
    gen_set_label(l2);
373
}
374

  
375
static void gen_fbcond(DisasContext *ctx, TCGCond cond, int ra, int32_t disp)
376
{
377
    int lab_true;
378

  
379
    if (unlikely(ra == 31)) {
380
        /* Very uncommon case, but easier to optimize it to an integer
381
           comparison than continuing with the floating point comparison.  */
382
        gen_bcond(ctx, cond, ra, disp, 0);
383
        return;
384
    }
385

  
386
    lab_true = gen_new_label();
387
    gen_fbcond_internal(cond, cpu_fir[ra], lab_true);
388
    gen_bcond_pcload(ctx, disp, lab_true);
368 389
}
369 390

  
370 391
static inline void gen_cmov(TCGCond inv_cond, int ra, int rb, int rc,
......
399 420
    gen_set_label(l1);
400 421
}
401 422

  
423
static void gen_fcmov(TCGCond inv_cond, int ra, int rb, int rc)
424
{
425
    TCGv va = cpu_fir[ra];
426
    int l1;
427

  
428
    if (unlikely(rc == 31))
429
        return;
430
    if (unlikely(ra == 31)) {
431
        /* ??? Assume that the temporary is reclaimed at the branch.  */
432
        va = tcg_const_i64(0);
433
    }
434

  
435
    l1 = gen_new_label();
436
    gen_fbcond_internal(inv_cond, va, l1);
437

  
438
    if (rb != 31)
439
        tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[rb]);
440
    else
441
        tcg_gen_movi_i64(cpu_fir[rc], 0);
442
    gen_set_label(l1);
443
}
444

  
402 445
#define FARITH2(name)                                       \
403 446
static inline void glue(gen_f, name)(int rb, int rc)        \
404 447
{                                                           \
......
482 525
FARITH3(cpysn)
483 526
FARITH3(cpyse)
484 527

  
485
#define FCMOV(name)                                                   \
486
static inline void glue(gen_f, name)(int ra, int rb, int rc)          \
487
{                                                                     \
488
    int l1;                                                           \
489
    TCGv tmp;                                                         \
490
                                                                      \
491
    if (unlikely(rc == 31))                                           \
492
        return;                                                       \
493
                                                                      \
494
    l1 = gen_new_label();                                             \
495
    tmp = tcg_temp_new();                                 \
496
    if (ra != 31) {                                                   \
497
        tmp = tcg_temp_new();                             \
498
        gen_helper_ ## name (tmp, cpu_fir[ra]);                       \
499
    } else  {                                                         \
500
        tmp = tcg_const_i64(0);                                       \
501
        gen_helper_ ## name (tmp, tmp);                               \
502
    }                                                                 \
503
    tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1);                     \
504
    if (rb != 31)                                                     \
505
        tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);                    \
506
    else                                                              \
507
        tcg_gen_movi_i64(cpu_fir[rc], 0);                             \
508
    gen_set_label(l1);                                                \
509
}
510
FCMOV(cmpfeq)
511
FCMOV(cmpfne)
512
FCMOV(cmpflt)
513
FCMOV(cmpfge)
514
FCMOV(cmpfle)
515
FCMOV(cmpfgt)
516

  
517 528
static inline uint64_t zapnot_mask(uint8_t lit)
518 529
{
519 530
    uint64_t mask = 0;
......
1871 1882
            break;
1872 1883
        case 0x02A:
1873 1884
            /* FCMOVEQ */
1874
            gen_fcmpfeq(ra, rb, rc);
1885
            gen_fcmov(TCG_COND_NE, ra, rb, rc);
1875 1886
            break;
1876 1887
        case 0x02B:
1877 1888
            /* FCMOVNE */
1878
            gen_fcmpfne(ra, rb, rc);
1889
            gen_fcmov(TCG_COND_EQ, ra, rb, rc);
1879 1890
            break;
1880 1891
        case 0x02C:
1881 1892
            /* FCMOVLT */
1882
            gen_fcmpflt(ra, rb, rc);
1893
            gen_fcmov(TCG_COND_GE, ra, rb, rc);
1883 1894
            break;
1884 1895
        case 0x02D:
1885 1896
            /* FCMOVGE */
1886
            gen_fcmpfge(ra, rb, rc);
1897
            gen_fcmov(TCG_COND_LT, ra, rb, rc);
1887 1898
            break;
1888 1899
        case 0x02E:
1889 1900
            /* FCMOVLE */
1890
            gen_fcmpfle(ra, rb, rc);
1901
            gen_fcmov(TCG_COND_GT, ra, rb, rc);
1891 1902
            break;
1892 1903
        case 0x02F:
1893 1904
            /* FCMOVGT */
1894
            gen_fcmpfgt(ra, rb, rc);
1905
            gen_fcmov(TCG_COND_LE, ra, rb, rc);
1895 1906
            break;
1896 1907
        case 0x030:
1897 1908
            /* CVTQL */
......
2482 2493
        ret = 1;
2483 2494
        break;
2484 2495
    case 0x31: /* FBEQ */
2496
        gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
2497
        ret = 1;
2498
        break;
2485 2499
    case 0x32: /* FBLT */
2500
        gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
2501
        ret = 1;
2502
        break;
2486 2503
    case 0x33: /* FBLE */
2487
        gen_fbcond(ctx, opc, ra, disp21);
2504
        gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
2488 2505
        ret = 1;
2489 2506
        break;
2490 2507
    case 0x34:
......
2495 2512
        ret = 1;
2496 2513
        break;
2497 2514
    case 0x35: /* FBNE */
2515
        gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
2516
        ret = 1;
2517
        break;
2498 2518
    case 0x36: /* FBGE */
2519
        gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
2520
        ret = 1;
2521
        break;
2499 2522
    case 0x37: /* FBGT */
2500
        gen_fbcond(ctx, opc, ra, disp21);
2523
        gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
2501 2524
        ret = 1;
2502 2525
        break;
2503 2526
    case 0x38:

Also available in: Unified diff