Revision 0085bd51

b/tcg/hppa/tcg-target.c
97 97
   Copied from gcc sources.  */
98 98
static inline int or_mask_p(tcg_target_ulong mask)
99 99
{
100
    if (mask == 0 || mask == -1) {
101
        return 0;
102
    }
100 103
    mask += mask & -mask;
101 104
    return (mask & (mask - 1)) == 0;
102 105
}
......
213 216
    case 'K':
214 217
        ct->ct |= TCG_CT_CONST_MS11;
215 218
        break;
219
    case 'M':
220
        ct->ct |= TCG_CT_CONST_AND;
221
        break;
222
    case 'O':
223
        ct->ct |= TCG_CT_CONST_OR;
224
        break;
216 225
    default:
217 226
        return -1;
218 227
    }
......
236 245
        return check_fit_tl(val, 11);
237 246
    } else if (ct & TCG_CT_CONST_MS11) {
238 247
        return check_fit_tl(-val, 11);
248
    } else if (ct & TCG_CT_CONST_AND) {
249
        return and_mask_p(val);
250
    } else if (ct & TCG_CT_CONST_OR) {
251
        return or_mask_p(val);
239 252
    }
240 253
    return 0;
241 254
}
......
474 487

  
475 488
static void tcg_out_ori(TCGContext *s, int ret, int arg, tcg_target_ulong m)
476 489
{
477
    if (m == 0) {
478
        tcg_out_mov(s, ret, arg);
479
    } else if (m == -1) {
480
        tcg_out_movi(s, TCG_TYPE_I32, ret, -1);
481
    } else if (or_mask_p(m)) {
482
        int bs0, bs1;
483

  
484
        for (bs0 = 0; bs0 < 32; bs0++) {
485
            if ((m & (1u << bs0)) != 0) {
486
                break;
487
            }
490
    int bs0, bs1;
491

  
492
    /* Note that the argument is constrained to match or_mask_p.  */
493
    for (bs0 = 0; bs0 < 32; bs0++) {
494
        if ((m & (1u << bs0)) != 0) {
495
            break;
488 496
        }
489
        for (bs1 = bs0; bs1 < 32; bs1++) {
490
            if ((m & (1u << bs1)) == 0) {
491
                break;
492
            }
497
    }
498
    for (bs1 = bs0; bs1 < 32; bs1++) {
499
        if ((m & (1u << bs1)) == 0) {
500
            break;
493 501
        }
494
        assert(bs1 == 32 || (1ul << bs1) > m);
495

  
496
        tcg_out_mov(s, ret, arg);
497
        tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1)
498
                  | INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0));
499
    } else {
500
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m);
501
        tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_OR);
502 502
    }
503
    assert(bs1 == 32 || (1ul << bs1) > m);
504

  
505
    tcg_out_mov(s, ret, arg);
506
    tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1)
507
              | INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0));
503 508
}
504 509

  
505 510
static void tcg_out_andi(TCGContext *s, int ret, int arg, tcg_target_ulong m)
506 511
{
507
    if (m == 0) {
508
        tcg_out_mov(s, ret, TCG_REG_R0);
509
    } else if (m == -1) {
510
        tcg_out_mov(s, ret, arg);
511
    } else if (and_mask_p(m)) {
512
        int ls0, ls1, ms0;
512
    int ls0, ls1, ms0;
513 513

  
514
        for (ls0 = 0; ls0 < 32; ls0++) {
515
            if ((m & (1u << ls0)) == 0) {
516
                break;
517
            }
514
    /* Note that the argument is constrained to match and_mask_p.  */
515
    for (ls0 = 0; ls0 < 32; ls0++) {
516
        if ((m & (1u << ls0)) == 0) {
517
            break;
518 518
        }
519
        for (ls1 = ls0; ls1 < 32; ls1++) {
520
            if ((m & (1u << ls1)) != 0) {
521
                break;
522
            }
519
    }
520
    for (ls1 = ls0; ls1 < 32; ls1++) {
521
        if ((m & (1u << ls1)) != 0) {
522
            break;
523 523
        }
524
        for (ms0 = ls1; ms0 < 32; ms0++) {
525
            if ((m & (1u << ms0)) == 0) {
526
                break;
527
            }
524
    }
525
    for (ms0 = ls1; ms0 < 32; ms0++) {
526
        if ((m & (1u << ms0)) == 0) {
527
            break;
528 528
        }
529
        assert (ms0 == 32);
529
    }
530
    assert (ms0 == 32);
530 531

  
531
        if (ls1 == 32) {
532
            tcg_out_extr(s, ret, arg, 0, ls0, 0);
533
        } else {
534
            tcg_out_mov(s, ret, arg);
535
            tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0)
536
                      | INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0));
537
        }
532
    if (ls1 == 32) {
533
        tcg_out_extr(s, ret, arg, 0, ls0, 0);
538 534
    } else {
539
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m);
540
        tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_AND);
535
        tcg_out_mov(s, ret, arg);
536
        tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0)
537
                  | INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0));
541 538
    }
542 539
}
543 540

  
......
1539 1536

  
1540 1537
    { INDEX_op_add_i32, { "r", "rZ", "ri" } },
1541 1538
    { INDEX_op_sub_i32, { "r", "rI", "ri" } },
1542
    { INDEX_op_and_i32, { "r", "rZ", "ri" } },
1543
    { INDEX_op_or_i32, { "r", "rZ", "ri" } },
1539
    { INDEX_op_and_i32, { "r", "rZ", "rM" } },
1540
    { INDEX_op_or_i32, { "r", "rZ", "rO" } },
1544 1541
    { INDEX_op_xor_i32, { "r", "rZ", "rZ" } },
1545
    { INDEX_op_andc_i32, { "r", "rZ", "ri" } },
1542
    /* Note that the second argument will be inverted, which means
1543
       we want a constant whose inversion matches M, and that O = ~M.
1544
       See the implementation of and_mask_p.  */
1545
    { INDEX_op_andc_i32, { "r", "rZ", "rO" } },
1546 1546

  
1547 1547
    { INDEX_op_mul_i32, { "r", "r", "r" } },
1548 1548
    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
b/tcg/hppa/tcg-target.h
73 73
#define TCG_CT_CONST_S5   0x0200
74 74
#define TCG_CT_CONST_S11  0x0400
75 75
#define TCG_CT_CONST_MS11 0x0800
76
#define TCG_CT_CONST_AND  0x1000
77
#define TCG_CT_CONST_OR   0x2000
76 78

  
77 79
/* used for function call generation */
78 80
#define TCG_REG_CALL_STACK TCG_REG_SP

Also available in: Unified diff