Revision 161f85e6 target-mips/translate.c

b/target-mips/translate.c
267 267
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
268 268
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
269 269
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
270
    /* Loongson 2F */
271
    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
272
    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
273
    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
274
    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
275
    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
276
    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
277
    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
278
    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
279
    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
280
    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
281
    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
282
    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
270 283
    /* Misc */
271 284
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
272 285
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
......
293 306
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
294 307
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
295 308
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
309

  
310
    /* Loongson 2E */
311
    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
312
    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
313
    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
314
    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
315
    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
316
    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
317
    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
318
    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
319
    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
320
    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
321
    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
322
    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
296 323
};
297 324

  
298 325
/* BSHFL opcodes */
......
2325 2352
    tcg_temp_free(t0);
2326 2353
}
2327 2354

  
2355
/* Godson integer instructions */
2356
static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2357
                                int rd, int rs, int rt)
2358
{
2359
    const char *opn = "loongson";
2360
    TCGv t0, t1;
2361

  
2362
    if (rd == 0) {
2363
        /* Treat as NOP. */
2364
        MIPS_DEBUG("NOP");
2365
        return;
2366
    }
2367

  
2368
    switch (opc) {
2369
    case OPC_MULT_G_2E:
2370
    case OPC_MULT_G_2F:
2371
    case OPC_MULTU_G_2E:
2372
    case OPC_MULTU_G_2F:
2373
#if defined(TARGET_MIPS64)
2374
    case OPC_DMULT_G_2E:
2375
    case OPC_DMULT_G_2F:
2376
    case OPC_DMULTU_G_2E:
2377
    case OPC_DMULTU_G_2F:
2378
#endif
2379
        t0 = tcg_temp_new();
2380
        t1 = tcg_temp_new();
2381
        break;
2382
    default:
2383
        t0 = tcg_temp_local_new();
2384
        t1 = tcg_temp_local_new();
2385
        break;
2386
    }
2387

  
2388
    gen_load_gpr(t0, rs);
2389
    gen_load_gpr(t1, rt);
2390

  
2391
    switch (opc) {
2392
    case OPC_MULT_G_2E:
2393
    case OPC_MULT_G_2F:
2394
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2395
        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2396
        opn = "mult.g";
2397
        break;
2398
    case OPC_MULTU_G_2E:
2399
    case OPC_MULTU_G_2F:
2400
        tcg_gen_ext32u_tl(t0, t0);
2401
        tcg_gen_ext32u_tl(t1, t1);
2402
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2403
        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2404
        opn = "multu.g";
2405
        break;
2406
    case OPC_DIV_G_2E:
2407
    case OPC_DIV_G_2F:
2408
        {
2409
            int l1 = gen_new_label();
2410
            int l2 = gen_new_label();
2411
            int l3 = gen_new_label();
2412
            tcg_gen_ext32s_tl(t0, t0);
2413
            tcg_gen_ext32s_tl(t1, t1);
2414
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2415
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2416
            tcg_gen_br(l3);
2417
            gen_set_label(l1);
2418
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2419
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2420
            tcg_gen_mov_tl(cpu_gpr[rd], t0);
2421
            tcg_gen_br(l3);
2422
            gen_set_label(l2);
2423
            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2424
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2425
            gen_set_label(l3);
2426
        }
2427
        opn = "div.g";
2428
        break;
2429
    case OPC_DIVU_G_2E:
2430
    case OPC_DIVU_G_2F:
2431
        {
2432
            int l1 = gen_new_label();
2433
            int l2 = gen_new_label();
2434
            tcg_gen_ext32u_tl(t0, t0);
2435
            tcg_gen_ext32u_tl(t1, t1);
2436
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2437
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2438
            tcg_gen_br(l2);
2439
            gen_set_label(l1);
2440
            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2441
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2442
            gen_set_label(l2);
2443
        }
2444
        opn = "divu.g";
2445
        break;
2446
    case OPC_MOD_G_2E:
2447
    case OPC_MOD_G_2F:
2448
        {
2449
            int l1 = gen_new_label();
2450
            int l2 = gen_new_label();
2451
            int l3 = gen_new_label();
2452
            tcg_gen_ext32u_tl(t0, t0);
2453
            tcg_gen_ext32u_tl(t1, t1);
2454
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2455
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2456
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2457
            gen_set_label(l1);
2458
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2459
            tcg_gen_br(l3);
2460
            gen_set_label(l2);
2461
            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2462
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2463
            gen_set_label(l3);
2464
        }
2465
        opn = "mod.g";
2466
        break;
2467
    case OPC_MODU_G_2E:
2468
    case OPC_MODU_G_2F:
2469
        {
2470
            int l1 = gen_new_label();
2471
            int l2 = gen_new_label();
2472
            tcg_gen_ext32u_tl(t0, t0);
2473
            tcg_gen_ext32u_tl(t1, t1);
2474
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2475
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2476
            tcg_gen_br(l2);
2477
            gen_set_label(l1);
2478
            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2479
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2480
            gen_set_label(l2);
2481
        }
2482
        opn = "modu.g";
2483
        break;
2484
#if defined(TARGET_MIPS64)
2485
    case OPC_DMULT_G_2E:
2486
    case OPC_DMULT_G_2F:
2487
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2488
        opn = "dmult.g";
2489
        break;
2490
    case OPC_DMULTU_G_2E:
2491
    case OPC_DMULTU_G_2F:
2492
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2493
        opn = "dmultu.g";
2494
        break;
2495
    case OPC_DDIV_G_2E:
2496
    case OPC_DDIV_G_2F:
2497
        {
2498
            int l1 = gen_new_label();
2499
            int l2 = gen_new_label();
2500
            int l3 = gen_new_label();
2501
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2502
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2503
            tcg_gen_br(l3);
2504
            gen_set_label(l1);
2505
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2506
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2507
            tcg_gen_mov_tl(cpu_gpr[rd], t0);
2508
            tcg_gen_br(l3);
2509
            gen_set_label(l2);
2510
            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2511
            gen_set_label(l3);
2512
        }
2513
        opn = "ddiv.g";
2514
        break;
2515
    case OPC_DDIVU_G_2E:
2516
    case OPC_DDIVU_G_2F:
2517
        {
2518
            int l1 = gen_new_label();
2519
            int l2 = gen_new_label();
2520
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2521
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2522
            tcg_gen_br(l2);
2523
            gen_set_label(l1);
2524
            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2525
            gen_set_label(l2);
2526
        }
2527
        opn = "ddivu.g";
2528
        break;
2529
    case OPC_DMOD_G_2E:
2530
    case OPC_DMOD_G_2F:
2531
        {
2532
            int l1 = gen_new_label();
2533
            int l2 = gen_new_label();
2534
            int l3 = gen_new_label();
2535
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2536
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2537
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2538
            gen_set_label(l1);
2539
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2540
            tcg_gen_br(l3);
2541
            gen_set_label(l2);
2542
            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2543
            gen_set_label(l3);
2544
        }
2545
        opn = "dmod.g";
2546
        break;
2547
    case OPC_DMODU_G_2E:
2548
    case OPC_DMODU_G_2F:
2549
        {
2550
            int l1 = gen_new_label();
2551
            int l2 = gen_new_label();
2552
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2553
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2554
            tcg_gen_br(l2);
2555
            gen_set_label(l1);
2556
            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2557
            gen_set_label(l2);
2558
        }
2559
        opn = "dmodu.g";
2560
        break;
2561
#endif
2562
    }
2563

  
2564
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2565
    tcg_temp_free(t0);
2566
    tcg_temp_free(t1);
2567
}
2568

  
2328 2569
/* Traps */
2329 2570
static void gen_trap (DisasContext *ctx, uint32_t opc,
2330 2571
                      int rs, int rt, int16_t imm)
......
11596 11837
            }
11597 11838
            /* Treat as NOP. */
11598 11839
            break;
11840
        case OPC_DIV_G_2F:
11841
        case OPC_DIVU_G_2F:
11842
        case OPC_MULT_G_2F:
11843
        case OPC_MULTU_G_2F:
11844
        case OPC_MOD_G_2F:
11845
        case OPC_MODU_G_2F:
11846
            check_insn(env, ctx, INSN_LOONGSON2F);
11847
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11848
            break;
11599 11849
#if defined(TARGET_MIPS64)
11600 11850
        case OPC_DCLO:
11601 11851
        case OPC_DCLZ:
......
11603 11853
            check_mips_64(ctx);
11604 11854
            gen_cl(ctx, op1, rd, rs);
11605 11855
            break;
11856
        case OPC_DMULT_G_2F:
11857
        case OPC_DMULTU_G_2F:
11858
        case OPC_DDIV_G_2F:
11859
        case OPC_DDIVU_G_2F:
11860
        case OPC_DMOD_G_2F:
11861
        case OPC_DMODU_G_2F:
11862
            check_insn(env, ctx, INSN_LOONGSON2F);
11863
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11864
            break;
11606 11865
#endif
11607 11866
        default:            /* Invalid */
11608 11867
            MIPS_INVAL("special2");
......
11651 11910
                tcg_temp_free(t0);
11652 11911
            }
11653 11912
            break;
11913
        case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
11914
        case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
11915
        case OPC_MOD_G_2E ... OPC_MODU_G_2E:
11916
            check_insn(env, ctx, INSN_LOONGSON2E);
11917
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11918
            break;
11654 11919
#if defined(TARGET_MIPS64)
11655 11920
        case OPC_DEXTM ... OPC_DEXT:
11656 11921
        case OPC_DINSM ... OPC_DINS:
......
11664 11929
            op2 = MASK_DBSHFL(ctx->opcode);
11665 11930
            gen_bshfl(ctx, op2, rt, rd);
11666 11931
            break;
11932
        case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
11933
        case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
11934
        case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
11935
            check_insn(env, ctx, INSN_LOONGSON2E);
11936
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11937
            break;
11667 11938
#endif
11668 11939
        default:            /* Invalid */
11669 11940
            MIPS_INVAL("special3");

Also available in: Unified diff