Revision 03271524

b/tcg/aarch64/tcg-target.h
61 61
#define TCG_TARGET_HAS_sub2_i32         0
62 62
#define TCG_TARGET_HAS_mulu2_i32        0
63 63
#define TCG_TARGET_HAS_muls2_i32        0
64
#define TCG_TARGET_HAS_muluh_i32        0
65
#define TCG_TARGET_HAS_mulsh_i32        0
64 66

  
65 67
#define TCG_TARGET_HAS_div_i64          0
66 68
#define TCG_TARGET_HAS_rem_i64          0
......
87 89
#define TCG_TARGET_HAS_sub2_i64         0
88 90
#define TCG_TARGET_HAS_mulu2_i64        0
89 91
#define TCG_TARGET_HAS_muls2_i64        0
92
#define TCG_TARGET_HAS_muluh_i64        0
93
#define TCG_TARGET_HAS_mulsh_i64        0
90 94

  
91 95
enum {
92 96
    TCG_AREG0 = TCG_REG_X19,
b/tcg/arm/tcg-target.h
80 80
#define TCG_TARGET_HAS_deposit_i32      1
81 81
#define TCG_TARGET_HAS_movcond_i32      1
82 82
#define TCG_TARGET_HAS_muls2_i32        1
83
#define TCG_TARGET_HAS_muluh_i32        0
84
#define TCG_TARGET_HAS_mulsh_i32        0
83 85
#define TCG_TARGET_HAS_div_i32          use_idiv_instructions
84 86
#define TCG_TARGET_HAS_rem_i32          0
85 87

  
b/tcg/hppa/tcg-target.h
100 100
#define TCG_TARGET_HAS_deposit_i32      1
101 101
#define TCG_TARGET_HAS_movcond_i32      1
102 102
#define TCG_TARGET_HAS_muls2_i32        0
103
#define TCG_TARGET_HAS_muluh_i32        0
104
#define TCG_TARGET_HAS_mulsh_i32        0
103 105

  
104 106
/* optional instructions automatically implemented */
105 107
#define TCG_TARGET_HAS_neg_i32          0 /* sub rd, 0, rs */
b/tcg/i386/tcg-target.h
96 96
#define TCG_TARGET_HAS_sub2_i32         1
97 97
#define TCG_TARGET_HAS_mulu2_i32        1
98 98
#define TCG_TARGET_HAS_muls2_i32        1
99
#define TCG_TARGET_HAS_muluh_i32        0
100
#define TCG_TARGET_HAS_mulsh_i32        0
99 101

  
100 102
#if TCG_TARGET_REG_BITS == 64
101 103
#define TCG_TARGET_HAS_div2_i64         1
......
122 124
#define TCG_TARGET_HAS_sub2_i64         1
123 125
#define TCG_TARGET_HAS_mulu2_i64        1
124 126
#define TCG_TARGET_HAS_muls2_i64        1
127
#define TCG_TARGET_HAS_muluh_i64        0
128
#define TCG_TARGET_HAS_mulsh_i64        0
125 129
#endif
126 130

  
127 131
#define TCG_TARGET_deposit_i32_valid(ofs, len) \
b/tcg/ia64/tcg-target.h
146 146
#define TCG_TARGET_HAS_mulu2_i64        0
147 147
#define TCG_TARGET_HAS_muls2_i32        0
148 148
#define TCG_TARGET_HAS_muls2_i64        0
149
#define TCG_TARGET_HAS_muluh_i32        0
150
#define TCG_TARGET_HAS_muluh_i64        0
151
#define TCG_TARGET_HAS_mulsh_i32        0
152
#define TCG_TARGET_HAS_mulsh_i64        0
149 153

  
150 154
#define TCG_TARGET_deposit_i32_valid(ofs, len) ((len) <= 16)
151 155
#define TCG_TARGET_deposit_i64_valid(ofs, len) ((len) <= 16)
b/tcg/mips/tcg-target.h
89 89
#define TCG_TARGET_HAS_eqv_i32          0
90 90
#define TCG_TARGET_HAS_nand_i32         0
91 91
#define TCG_TARGET_HAS_muls2_i32        1
92
#define TCG_TARGET_HAS_muluh_i32        0
93
#define TCG_TARGET_HAS_mulsh_i32        0
92 94

  
93 95
/* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
94 96
#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
b/tcg/optimize.c
198 198

  
199 199
static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
200 200
{
201
    uint64_t l64, h64;
202

  
201 203
    switch (op) {
202 204
    CASE_OP_32_64(add):
203 205
        return x + y;
......
290 292
    case INDEX_op_ext32u_i64:
291 293
        return (uint32_t)x;
292 294

  
295
    case INDEX_op_muluh_i32:
296
        return ((uint64_t)(uint32_t)x * (uint32_t)y) >> 32;
297
    case INDEX_op_mulsh_i32:
298
        return ((int64_t)(int32_t)x * (int32_t)y) >> 32;
299

  
300
    case INDEX_op_muluh_i64:
301
        mulu64(&l64, &h64, x, y);
302
        return h64;
303
    case INDEX_op_mulsh_i64:
304
        muls64(&l64, &h64, x, y);
305
        return h64;
306

  
293 307
    default:
294 308
        fprintf(stderr,
295 309
                "Unrecognized operation %d in do_constant_folding.\n", op);
......
531 545
        CASE_OP_32_64(eqv):
532 546
        CASE_OP_32_64(nand):
533 547
        CASE_OP_32_64(nor):
548
        CASE_OP_32_64(muluh):
549
        CASE_OP_32_64(mulsh):
534 550
            swap_commutative(args[0], &args[1], &args[2]);
535 551
            break;
536 552
        CASE_OP_32_64(brcond):
......
771 787
        switch (op) {
772 788
        CASE_OP_32_64(and):
773 789
        CASE_OP_32_64(mul):
790
        CASE_OP_32_64(muluh):
791
        CASE_OP_32_64(mulsh):
774 792
            if ((temps[args[2]].state == TCG_TEMP_CONST
775 793
                && temps[args[2]].val == 0)) {
776 794
                s->gen_opc_buf[op_index] = op_to_movi(op);
......
882 900
        CASE_OP_32_64(eqv):
883 901
        CASE_OP_32_64(nand):
884 902
        CASE_OP_32_64(nor):
903
        CASE_OP_32_64(muluh):
904
        CASE_OP_32_64(mulsh):
885 905
            if (temps[args[1]].state == TCG_TEMP_CONST
886 906
                && temps[args[2]].state == TCG_TEMP_CONST) {
887 907
                s->gen_opc_buf[op_index] = op_to_movi(op);
b/tcg/ppc/tcg-target.h
96 96
#define TCG_TARGET_HAS_deposit_i32      1
97 97
#define TCG_TARGET_HAS_movcond_i32      1
98 98
#define TCG_TARGET_HAS_muls2_i32        0
99
#define TCG_TARGET_HAS_muluh_i32        0
100
#define TCG_TARGET_HAS_mulsh_i32        0
99 101

  
100 102
#define TCG_AREG0 TCG_REG_R27
101 103

  
b/tcg/ppc64/tcg-target.h
95 95
#define TCG_TARGET_HAS_sub2_i32         0
96 96
#define TCG_TARGET_HAS_mulu2_i32        0
97 97
#define TCG_TARGET_HAS_muls2_i32        0
98
#define TCG_TARGET_HAS_muluh_i32        0
99
#define TCG_TARGET_HAS_mulsh_i32        0
98 100

  
99 101
#define TCG_TARGET_HAS_div_i64          1
100 102
#define TCG_TARGET_HAS_rem_i64          0
......
118 120
#define TCG_TARGET_HAS_sub2_i64         1
119 121
#define TCG_TARGET_HAS_mulu2_i64        1
120 122
#define TCG_TARGET_HAS_muls2_i64        1
123
#define TCG_TARGET_HAS_muluh_i64        0
124
#define TCG_TARGET_HAS_mulsh_i64        0
121 125

  
122 126
#define TCG_AREG0 TCG_REG_R27
123 127

  
b/tcg/s390/tcg-target.h
69 69
#define TCG_TARGET_HAS_sub2_i32         1
70 70
#define TCG_TARGET_HAS_mulu2_i32        0
71 71
#define TCG_TARGET_HAS_muls2_i32        0
72
#define TCG_TARGET_HAS_muluh_i32        0
73
#define TCG_TARGET_HAS_mulsh_i32        0
72 74

  
73 75
#define TCG_TARGET_HAS_div2_i64         1
74 76
#define TCG_TARGET_HAS_rot_i64          1
......
94 96
#define TCG_TARGET_HAS_sub2_i64         1
95 97
#define TCG_TARGET_HAS_mulu2_i64        1
96 98
#define TCG_TARGET_HAS_muls2_i64        0
99
#define TCG_TARGET_HAS_muluh_i64        0
100
#define TCG_TARGET_HAS_mulsh_i64        0
97 101

  
98 102
extern bool tcg_target_deposit_valid(int ofs, int len);
99 103
#define TCG_TARGET_deposit_i32_valid  tcg_target_deposit_valid
b/tcg/sparc/tcg-target.h
107 107
#define TCG_TARGET_HAS_sub2_i32         1
108 108
#define TCG_TARGET_HAS_mulu2_i32        1
109 109
#define TCG_TARGET_HAS_muls2_i32        0
110
#define TCG_TARGET_HAS_muluh_i32        0
111
#define TCG_TARGET_HAS_mulsh_i32        0
110 112

  
111 113
#if TCG_TARGET_REG_BITS == 64
112 114
#define TCG_TARGET_HAS_div_i64          1
......
134 136
#define TCG_TARGET_HAS_sub2_i64         0
135 137
#define TCG_TARGET_HAS_mulu2_i64        0
136 138
#define TCG_TARGET_HAS_muls2_i64        0
139
#define TCG_TARGET_HAS_muluh_i64        0
140
#define TCG_TARGET_HAS_mulsh_i64        0
137 141
#endif
138 142

  
139 143
#define TCG_AREG0 TCG_REG_I0
b/tcg/tcg-op.h
1039 1039
    t0 = tcg_temp_new_i64();
1040 1040
    t1 = tcg_temp_new_i32();
1041 1041

  
1042
    tcg_gen_op4_i32(INDEX_op_mulu2_i32, TCGV_LOW(t0), TCGV_HIGH(t0),
1043
                    TCGV_LOW(arg1), TCGV_LOW(arg2));
1044
    /* Allow the optimizer room to replace mulu2 with two moves.  */
1045
    tcg_gen_op0(INDEX_op_nop);
1042
    if (TCG_TARGET_HAS_mulu2_i32) {
1043
        tcg_gen_op4_i32(INDEX_op_mulu2_i32, TCGV_LOW(t0), TCGV_HIGH(t0),
1044
                        TCGV_LOW(arg1), TCGV_LOW(arg2));
1045
        /* Allow the optimizer room to replace mulu2 with two moves.  */
1046
        tcg_gen_op0(INDEX_op_nop);
1047
    } else {
1048
        tcg_debug_assert(TCG_TARGET_HAS_muluh_i32);
1049
        tcg_gen_op3_i32(INDEX_op_mul_i32, TCGV_LOW(t0),
1050
                        TCGV_LOW(arg1), TCGV_LOW(arg2));
1051
        tcg_gen_op3_i32(INDEX_op_muluh_i32, TCGV_HIGH(t0),
1052
                        TCGV_LOW(arg1), TCGV_LOW(arg2));
1053
    }
1046 1054

  
1047 1055
    tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
1048 1056
    tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
......
2401 2409
        tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
2402 2410
        /* Allow the optimizer room to replace mulu2 with two moves.  */
2403 2411
        tcg_gen_op0(INDEX_op_nop);
2412
    } else if (TCG_TARGET_HAS_muluh_i32) {
2413
        TCGv_i32 t = tcg_temp_new_i32();
2414
        tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
2415
        tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
2416
        tcg_gen_mov_i32(rl, t);
2417
        tcg_temp_free_i32(t);
2404 2418
    } else {
2405 2419
        TCGv_i64 t0 = tcg_temp_new_i64();
2406 2420
        TCGv_i64 t1 = tcg_temp_new_i64();
......
2420 2434
        tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
2421 2435
        /* Allow the optimizer room to replace muls2 with two moves.  */
2422 2436
        tcg_gen_op0(INDEX_op_nop);
2437
    } else if (TCG_TARGET_HAS_mulsh_i32) {
2438
        TCGv_i32 t = tcg_temp_new_i32();
2439
        tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
2440
        tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
2441
        tcg_gen_mov_i32(rl, t);
2442
        tcg_temp_free_i32(t);
2423 2443
    } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_mulu2_i32) {
2424 2444
        TCGv_i32 t0 = tcg_temp_new_i32();
2425 2445
        TCGv_i32 t1 = tcg_temp_new_i32();
......
2499 2519
        tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
2500 2520
        /* Allow the optimizer room to replace mulu2 with two moves.  */
2501 2521
        tcg_gen_op0(INDEX_op_nop);
2522
    } else if (TCG_TARGET_HAS_muluh_i64) {
2523
        TCGv_i64 t = tcg_temp_new_i64();
2524
        tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
2525
        tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
2526
        tcg_gen_mov_i64(rl, t);
2527
        tcg_temp_free_i64(t);
2502 2528
    } else if (TCG_TARGET_HAS_mulu2_i64) {
2503 2529
        TCGv_i64 t0 = tcg_temp_new_i64();
2504 2530
        TCGv_i64 t1 = tcg_temp_new_i64();
......
2540 2566
        tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
2541 2567
        /* Allow the optimizer room to replace muls2 with two moves.  */
2542 2568
        tcg_gen_op0(INDEX_op_nop);
2569
    } else if (TCG_TARGET_HAS_mulsh_i64) {
2570
        TCGv_i64 t = tcg_temp_new_i64();
2571
        tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
2572
        tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
2573
        tcg_gen_mov_i64(rl, t);
2574
        tcg_temp_free_i64(t);
2543 2575
    } else {
2544 2576
        TCGv_i64 t0 = tcg_temp_new_i64();
2545 2577
        int sizemask = 0;
b/tcg/tcg-opc.h
91 91
DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_sub2_i32))
92 92
DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_mulu2_i32))
93 93
DEF(muls2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_muls2_i32))
94
DEF(muluh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i32))
95
DEF(mulsh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i32))
94 96
DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | IMPL(TCG_TARGET_REG_BITS == 32))
95 97
DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32))
96 98

  
......
167 169
DEF(sub2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_sub2_i64))
168 170
DEF(mulu2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulu2_i64))
169 171
DEF(muls2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muls2_i64))
172
DEF(muluh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i64))
173
DEF(mulsh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i64))
170 174

  
171 175
/* QEMU specific */
172 176
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
b/tcg/tcg.c
1252 1252
static void tcg_liveness_analysis(TCGContext *s)
1253 1253
{
1254 1254
    int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1255
    TCGOpcode op, op_new;
1255
    TCGOpcode op, op_new, op_new2;
1256 1256
    TCGArg *args;
1257 1257
    const TCGOpDef *def;
1258 1258
    uint8_t *dead_temps, *mem_temps;
1259 1259
    uint16_t dead_args;
1260 1260
    uint8_t sync_args;
1261
    bool have_op_new2;
1261 1262
    
1262 1263
    s->gen_opc_ptr++; /* skip end */
1263 1264

  
......
1394 1395
            goto do_not_remove;
1395 1396

  
1396 1397
        case INDEX_op_mulu2_i32:
1398
            op_new = INDEX_op_mul_i32;
1399
            op_new2 = INDEX_op_muluh_i32;
1400
            have_op_new2 = TCG_TARGET_HAS_muluh_i32;
1401
            goto do_mul2;
1397 1402
        case INDEX_op_muls2_i32:
1398 1403
            op_new = INDEX_op_mul_i32;
1404
            op_new2 = INDEX_op_mulsh_i32;
1405
            have_op_new2 = TCG_TARGET_HAS_mulsh_i32;
1399 1406
            goto do_mul2;
1400 1407
        case INDEX_op_mulu2_i64:
1408
            op_new = INDEX_op_mul_i64;
1409
            op_new2 = INDEX_op_muluh_i64;
1410
            have_op_new2 = TCG_TARGET_HAS_muluh_i64;
1411
            goto do_mul2;
1401 1412
        case INDEX_op_muls2_i64:
1402 1413
            op_new = INDEX_op_mul_i64;
1414
            op_new2 = INDEX_op_mulsh_i64;
1415
            have_op_new2 = TCG_TARGET_HAS_mulsh_i64;
1416
            goto do_mul2;
1403 1417
        do_mul2:
1404 1418
            args -= 4;
1405 1419
            nb_iargs = 2;
1406 1420
            nb_oargs = 2;
1407
            /* Likewise, test for the high part of the operation dead.  */
1408 1421
            if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1409 1422
                if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1423
                    /* Both parts of the operation are dead.  */
1410 1424
                    goto do_remove;
1411 1425
                }
1426
                /* The high part of the operation is dead; generate the low. */
1412 1427
                s->gen_opc_buf[op_index] = op = op_new;
1413 1428
                args[1] = args[2];
1414 1429
                args[2] = args[3];
1415
                assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1416
                tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1417
                /* Fall through and mark the single-word operation live.  */
1418
                nb_oargs = 1;
1430
            } else if (have_op_new2 && dead_temps[args[0]]
1431
                       && !mem_temps[args[0]]) {
1432
                /* The low part of the operation is dead; generate the high.  */
1433
                s->gen_opc_buf[op_index] = op = op_new2;
1434
                args[0] = args[1];
1435
                args[1] = args[2];
1436
                args[2] = args[3];
1437
            } else {
1438
                goto do_not_remove;
1419 1439
            }
1440
            assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1441
            tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1442
            /* Mark the single-word operation live.  */
1443
            nb_oargs = 1;
1420 1444
            goto do_not_remove;
1421 1445

  
1422 1446
        default:
b/tcg/tcg.h
85 85
#define TCG_TARGET_HAS_sub2_i64         0
86 86
#define TCG_TARGET_HAS_mulu2_i64        0
87 87
#define TCG_TARGET_HAS_muls2_i64        0
88
#define TCG_TARGET_HAS_muluh_i64        0
89
#define TCG_TARGET_HAS_mulsh_i64        0
88 90
/* Turn some undef macros into true macros.  */
89 91
#define TCG_TARGET_HAS_add2_i32         1
90 92
#define TCG_TARGET_HAS_sub2_i32         1
b/tcg/tci/tcg-target.h
76 76
#define TCG_TARGET_HAS_rot_i32          1
77 77
#define TCG_TARGET_HAS_movcond_i32      0
78 78
#define TCG_TARGET_HAS_muls2_i32        0
79
#define TCG_TARGET_HAS_muluh_i32        0
80
#define TCG_TARGET_HAS_mulsh_i32        0
79 81

  
80 82
#if TCG_TARGET_REG_BITS == 64
81 83
#define TCG_TARGET_HAS_bswap16_i64      1
......
100 102
#define TCG_TARGET_HAS_rot_i64          1
101 103
#define TCG_TARGET_HAS_movcond_i64      0
102 104
#define TCG_TARGET_HAS_muls2_i64        0
103

  
104 105
#define TCG_TARGET_HAS_add2_i32         0
105 106
#define TCG_TARGET_HAS_sub2_i32         0
106 107
#define TCG_TARGET_HAS_mulu2_i32        0
107 108
#define TCG_TARGET_HAS_add2_i64         0
108 109
#define TCG_TARGET_HAS_sub2_i64         0
109 110
#define TCG_TARGET_HAS_mulu2_i64        0
111
#define TCG_TARGET_HAS_muluh_i64        0
112
#define TCG_TARGET_HAS_mulsh_i64        0
110 113
#endif /* TCG_TARGET_REG_BITS == 64 */
111 114

  
112 115
/* Number of registers available.

Also available in: Unified diff