Revision 637af30c tcg/ppc64/tcg-target.c

b/tcg/ppc64/tcg-target.c
527 527
    }
528 528
}
529 529

  
530
static inline bool mask_operand(uint32_t c, int *mb, int *me)
530
static bool mask_operand(uint32_t c, int *mb, int *me)
531 531
{
532 532
    uint32_t lsb, test;
533 533

  
......
551 551
    return true;
552 552
}
553 553

  
554
static bool mask64_operand(uint64_t c, int *mb, int *me)
555
{
556
    uint64_t lsb;
557

  
558
    if (c == 0) {
559
        return false;
560
    }
561

  
562
    lsb = c & -c;
563
    /* Accept 1..10..0.  */
564
    if (c == -lsb) {
565
        *mb = 0;
566
        *me = clz64(lsb);
567
        return true;
568
    }
569
    /* Accept 0..01..1.  */
570
    if (lsb == 1 && (c & (c + 1)) == 0) {
571
        *mb = clz64(c + 1) + 1;
572
        *me = 63;
573
        return true;
574
    }
575
    return false;
576
}
577

  
554 578
static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
555 579
{
556 580
    int mb, me;
......
569 593
    }
570 594
}
571 595

  
596
static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c)
597
{
598
    int mb, me;
599

  
600
    if ((c & 0xffff) == c) {
601
        tcg_out32(s, ANDI | SAI(src, dst, c));
602
        return;
603
    } else if ((c & 0xffff0000) == c) {
604
        tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
605
        return;
606
    } else if (mask64_operand(c, &mb, &me)) {
607
        if (mb == 0) {
608
            tcg_out_rld(s, RLDICR, dst, src, 0, me);
609
        } else {
610
            tcg_out_rld(s, RLDICL, dst, src, 0, mb);
611
        }
612
    } else {
613
        tcg_out_movi(s, TCG_TYPE_I64, 0, c);
614
        tcg_out32(s, AND | SAB(src, dst, 0));
615
    }
616
}
617

  
572 618
static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c,
573 619
                           int op_lo, int op_hi)
574 620
{
......
1403 1449
        break;
1404 1450
    case INDEX_op_and_i64:
1405 1451
        if (const_args[2]) {
1406
            if ((args[2] & 0xffff) == args[2]) {
1407
                tcg_out32(s, ANDI | SAI(args[1], args[0], args[2]));
1408
            } else if ((args[2] & 0xffff0000) == args[2]) {
1409
                tcg_out32(s, ANDIS | SAI(args[1], args[0], args[2] >> 16));
1410
            } else {
1411
                tcg_out_movi (s, (opc == INDEX_op_and_i32
1412
                                  ? TCG_TYPE_I32
1413
                                  : TCG_TYPE_I64),
1414
                              0, args[2]);
1415
                tcg_out32 (s, AND | SAB (args[1], args[0], 0));
1416
            }
1452
            tcg_out_andi64(s, args[0], args[1], args[2]);
1453
        } else {
1454
            tcg_out32(s, AND | SAB(args[1], args[0], args[2]));
1417 1455
        }
1418
        else
1419
            tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
1420 1456
        break;
1421 1457
    case INDEX_op_or_i64:
1422 1458
    case INDEX_op_or_i32:

Also available in: Unified diff