Revision 6c073553

b/target-sparc/translate.c
2221 2221

  
2222 2222
    tcg_temp_free_i32(r_tl);
2223 2223
}
2224

  
2225
static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2,
2226
                     int width, bool cc, bool left)
2227
{
2228
    TCGv lo1, lo2, t1, t2;
2229
    uint64_t amask, tabl, tabr;
2230
    int shift, imask, omask;
2231

  
2232
    if (cc) {
2233
        tcg_gen_mov_tl(cpu_cc_src, s1);
2234
        tcg_gen_mov_tl(cpu_cc_src2, s2);
2235
        tcg_gen_sub_tl(cpu_cc_dst, s1, s2);
2236
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
2237
        dc->cc_op = CC_OP_SUB;
2238
    }
2239

  
2240
    /* Theory of operation: there are two tables, left and right (not to
2241
       be confused with the left and right versions of the opcode).  These
2242
       are indexed by the low 3 bits of the inputs.  To make things "easy",
2243
       these tables are loaded into two constants, TABL and TABR below.
2244
       The operation index = (input & imask) << shift calculates the index
2245
       into the constant, while val = (table >> index) & omask calculates
2246
       the value we're looking for.  */
2247
    switch (width) {
2248
    case 8:
2249
        imask = 0x7;
2250
        shift = 3;
2251
        omask = 0xff;
2252
        if (left) {
2253
            tabl = 0x80c0e0f0f8fcfeffULL;
2254
            tabr = 0xff7f3f1f0f070301ULL;
2255
        } else {
2256
            tabl = 0x0103070f1f3f7fffULL;
2257
            tabr = 0xfffefcf8f0e0c080ULL;
2258
        }
2259
        break;
2260
    case 16:
2261
        imask = 0x6;
2262
        shift = 1;
2263
        omask = 0xf;
2264
        if (left) {
2265
            tabl = 0x8cef;
2266
            tabr = 0xf731;
2267
        } else {
2268
            tabl = 0x137f;
2269
            tabr = 0xfec8;
2270
        }
2271
        break;
2272
    case 32:
2273
        imask = 0x4;
2274
        shift = 0;
2275
        omask = 0x3;
2276
        if (left) {
2277
            tabl = (2 << 2) | 3;
2278
            tabr = (3 << 2) | 1;
2279
        } else {
2280
            tabl = (1 << 2) | 3;
2281
            tabr = (3 << 2) | 2;
2282
        }
2283
        break;
2284
    default:
2285
        abort();
2286
    }
2287

  
2288
    lo1 = tcg_temp_new();
2289
    lo2 = tcg_temp_new();
2290
    tcg_gen_andi_tl(lo1, s1, imask);
2291
    tcg_gen_andi_tl(lo2, s2, imask);
2292
    tcg_gen_shli_tl(lo1, lo1, shift);
2293
    tcg_gen_shli_tl(lo2, lo2, shift);
2294

  
2295
    t1 = tcg_const_tl(tabl);
2296
    t2 = tcg_const_tl(tabr);
2297
    tcg_gen_shr_tl(lo1, t1, lo1);
2298
    tcg_gen_shr_tl(lo2, t2, lo2);
2299
    tcg_gen_andi_tl(dst, lo1, omask);
2300
    tcg_gen_andi_tl(lo2, lo2, omask);
2301

  
2302
    amask = -8;
2303
    if (AM_CHECK(dc)) {
2304
        amask &= 0xffffffffULL;
2305
    }
2306
    tcg_gen_andi_tl(s1, s1, amask);
2307
    tcg_gen_andi_tl(s2, s2, amask);
2308

  
2309
    /* We want to compute
2310
        dst = (s1 == s2 ? lo1 : lo1 & lo2).
2311
       We've already done dst = lo1, so this reduces to
2312
        dst &= (s1 == s2 ? -1 : lo2)
2313
       Which we perform by
2314
        lo2 |= -(s1 == s2)
2315
        dst &= lo2
2316
    */
2317
    tcg_gen_setcond_tl(TCG_COND_EQ, t1, s1, s2);
2318
    tcg_gen_neg_tl(t1, t1);
2319
    tcg_gen_or_tl(lo2, lo2, t1);
2320
    tcg_gen_and_tl(dst, dst, lo2);
2321

  
2322
    tcg_temp_free(lo1);
2323
    tcg_temp_free(lo2);
2324
    tcg_temp_free(t1);
2325
    tcg_temp_free(t2);
2326
}
2224 2327
#endif
2225 2328

  
2226 2329
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
......
3954 4057

  
3955 4058
                switch (opf) {
3956 4059
                case 0x000: /* VIS I edge8cc */
4060
                    CHECK_FPU_FEATURE(dc, VIS1);
4061
                    gen_movl_reg_TN(rs1, cpu_src1);
4062
                    gen_movl_reg_TN(rs2, cpu_src2);
4063
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 0);
4064
                    gen_movl_TN_reg(rd, cpu_dst);
4065
                    break;
3957 4066
                case 0x001: /* VIS II edge8n */
4067
                    CHECK_FPU_FEATURE(dc, VIS2);
4068
                    gen_movl_reg_TN(rs1, cpu_src1);
4069
                    gen_movl_reg_TN(rs2, cpu_src2);
4070
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 0);
4071
                    gen_movl_TN_reg(rd, cpu_dst);
4072
                    break;
3958 4073
                case 0x002: /* VIS I edge8lcc */
4074
                    CHECK_FPU_FEATURE(dc, VIS1);
4075
                    gen_movl_reg_TN(rs1, cpu_src1);
4076
                    gen_movl_reg_TN(rs2, cpu_src2);
4077
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 1);
4078
                    gen_movl_TN_reg(rd, cpu_dst);
4079
                    break;
3959 4080
                case 0x003: /* VIS II edge8ln */
4081
                    CHECK_FPU_FEATURE(dc, VIS2);
4082
                    gen_movl_reg_TN(rs1, cpu_src1);
4083
                    gen_movl_reg_TN(rs2, cpu_src2);
4084
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 1);
4085
                    gen_movl_TN_reg(rd, cpu_dst);
4086
                    break;
3960 4087
                case 0x004: /* VIS I edge16cc */
4088
                    CHECK_FPU_FEATURE(dc, VIS1);
4089
                    gen_movl_reg_TN(rs1, cpu_src1);
4090
                    gen_movl_reg_TN(rs2, cpu_src2);
4091
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 0);
4092
                    gen_movl_TN_reg(rd, cpu_dst);
4093
                    break;
3961 4094
                case 0x005: /* VIS II edge16n */
4095
                    CHECK_FPU_FEATURE(dc, VIS2);
4096
                    gen_movl_reg_TN(rs1, cpu_src1);
4097
                    gen_movl_reg_TN(rs2, cpu_src2);
4098
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 0);
4099
                    gen_movl_TN_reg(rd, cpu_dst);
4100
                    break;
3962 4101
                case 0x006: /* VIS I edge16lcc */
4102
                    CHECK_FPU_FEATURE(dc, VIS1);
4103
                    gen_movl_reg_TN(rs1, cpu_src1);
4104
                    gen_movl_reg_TN(rs2, cpu_src2);
4105
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 1);
4106
                    gen_movl_TN_reg(rd, cpu_dst);
4107
                    break;
3963 4108
                case 0x007: /* VIS II edge16ln */
4109
                    CHECK_FPU_FEATURE(dc, VIS2);
4110
                    gen_movl_reg_TN(rs1, cpu_src1);
4111
                    gen_movl_reg_TN(rs2, cpu_src2);
4112
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 1);
4113
                    gen_movl_TN_reg(rd, cpu_dst);
4114
                    break;
3964 4115
                case 0x008: /* VIS I edge32cc */
4116
                    CHECK_FPU_FEATURE(dc, VIS1);
4117
                    gen_movl_reg_TN(rs1, cpu_src1);
4118
                    gen_movl_reg_TN(rs2, cpu_src2);
4119
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 0);
4120
                    gen_movl_TN_reg(rd, cpu_dst);
4121
                    break;
3965 4122
                case 0x009: /* VIS II edge32n */
4123
                    CHECK_FPU_FEATURE(dc, VIS2);
4124
                    gen_movl_reg_TN(rs1, cpu_src1);
4125
                    gen_movl_reg_TN(rs2, cpu_src2);
4126
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 0);
4127
                    gen_movl_TN_reg(rd, cpu_dst);
4128
                    break;
3966 4129
                case 0x00a: /* VIS I edge32lcc */
4130
                    CHECK_FPU_FEATURE(dc, VIS1);
4131
                    gen_movl_reg_TN(rs1, cpu_src1);
4132
                    gen_movl_reg_TN(rs2, cpu_src2);
4133
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 1);
4134
                    gen_movl_TN_reg(rd, cpu_dst);
4135
                    break;
3967 4136
                case 0x00b: /* VIS II edge32ln */
3968
                    // XXX
3969
                    goto illegal_insn;
4137
                    CHECK_FPU_FEATURE(dc, VIS2);
4138
                    gen_movl_reg_TN(rs1, cpu_src1);
4139
                    gen_movl_reg_TN(rs2, cpu_src2);
4140
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 1);
4141
                    gen_movl_TN_reg(rd, cpu_dst);
4142
                    break;
3970 4143
                case 0x010: /* VIS I array8 */
3971 4144
                    CHECK_FPU_FEATURE(dc, VIS1);
3972 4145
                    cpu_src1 = get_src1(insn, cpu_src1);

Also available in: Unified diff