Revision e9c71dd1

b/target-mips/exec.h
79 79
void do_maddu (void);
80 80
void do_msub (void);
81 81
void do_msubu (void);
82
void do_muls (void);
83
void do_mulsu (void);
84
void do_macc (void);
85
void do_macchi (void);
86
void do_maccu (void);
87
void do_macchiu (void);
88
void do_msac (void);
89
void do_msachi (void);
90
void do_msacu (void);
91
void do_msachiu (void);
92
void do_mulhi (void);
93
void do_mulhiu (void);
94
void do_mulshi (void);
95
void do_mulshiu (void);
82 96
#endif
83 97
#if defined(TARGET_MIPS64)
84 98
void do_ddiv (void);
b/target-mips/mips-defs.h
4 4
/* If we want to use host float regs... */
5 5
//#define USE_HOST_FLOAT_REGS
6 6

  
7
/* real pages are variable size... */
7
/* Real pages are variable size... */
8 8
#define TARGET_PAGE_BITS 12
9 9
#define MIPS_TLB_MAX 128
10 10

  
......
29 29
#define		ISA_MIPS64	0x00000080
30 30
#define		ISA_MIPS64R2	0x00000100
31 31

  
32
/* MIPS ASE */
32
/* MIPS ASEs. */
33 33
#define		ASE_MIPS16	0x00001000
34 34
#define		ASE_MIPS3D	0x00002000
35 35
#define		ASE_MDMX	0x00004000
......
38 38
#define		ASE_MT		0x00020000
39 39
#define		ASE_SMARTMIPS	0x00040000
40 40

  
41
/* Chip specific instructions.   */
42
/* Currently void */
41
/* Chip specific instructions. */
42
#define		INSN_VR54XX	0x80000000
43 43

  
44
/* MIPS CPU defines.  */
44
/* MIPS CPU defines. */
45 45
#define		CPU_MIPS1	(ISA_MIPS1)
46 46
#define		CPU_MIPS2	(CPU_MIPS1 | ISA_MIPS2)
47 47
#define		CPU_MIPS3	(CPU_MIPS2 | ISA_MIPS3)
48 48
#define		CPU_MIPS4	(CPU_MIPS3 | ISA_MIPS4)
49
#define		CPU_VR54XX	(CPU_MIPS4 | INSN_VR54XX)
50

  
49 51
#define		CPU_MIPS5	(CPU_MIPS4 | ISA_MIPS5)
50 52

  
53
/* MIPS Technologies "Release 1" */
51 54
#define		CPU_MIPS32	(CPU_MIPS2 | ISA_MIPS32)
52 55
#define		CPU_MIPS64	(CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64)
53 56

  
57
/* MIPS Technologies "Release 2" */
54 58
#define		CPU_MIPS32R2	(CPU_MIPS32 | ISA_MIPS32R2)
55 59
#define		CPU_MIPS64R2	(CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2)
56 60

  
b/target-mips/op.c
781 781
    FORCE_RET();
782 782
}
783 783

  
784
/* Multiplication variants of the vr54xx. */
785
void op_muls (void)
786
{
787
    CALL_FROM_TB0(do_muls);
788
    FORCE_RET();
789
}
790

  
791
void op_mulsu (void)
792
{
793
    CALL_FROM_TB0(do_mulsu);
794
    FORCE_RET();
795
}
796

  
797
void op_macc (void)
798
{
799
    CALL_FROM_TB0(do_macc);
800
    FORCE_RET();
801
}
802

  
803
void op_macchi (void)
804
{
805
    CALL_FROM_TB0(do_macchi);
806
    FORCE_RET();
807
}
808

  
809
void op_maccu (void)
810
{
811
    CALL_FROM_TB0(do_maccu);
812
    FORCE_RET();
813
}
814
void op_macchiu (void)
815
{
816
    CALL_FROM_TB0(do_macchiu);
817
    FORCE_RET();
818
}
819

  
820
void op_msac (void)
821
{
822
    CALL_FROM_TB0(do_msac);
823
    FORCE_RET();
824
}
825

  
826
void op_msachi (void)
827
{
828
    CALL_FROM_TB0(do_msachi);
829
    FORCE_RET();
830
}
831

  
832
void op_msacu (void)
833
{
834
    CALL_FROM_TB0(do_msacu);
835
    FORCE_RET();
836
}
837

  
838
void op_msachiu (void)
839
{
840
    CALL_FROM_TB0(do_msachiu);
841
    FORCE_RET();
842
}
843

  
844
void op_mulhi (void)
845
{
846
    CALL_FROM_TB0(do_mulhi);
847
    FORCE_RET();
848
}
849

  
850
void op_mulhiu (void)
851
{
852
    CALL_FROM_TB0(do_mulhiu);
853
    FORCE_RET();
854
}
855

  
856
void op_mulshi (void)
857
{
858
    CALL_FROM_TB0(do_mulshi);
859
    FORCE_RET();
860
}
861

  
862
void op_mulshiu (void)
863
{
864
    CALL_FROM_TB0(do_mulshiu);
865
    FORCE_RET();
866
}
867

  
784 868
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
785 869

  
786 870
static always_inline uint64_t get_HILO (void)
......
795 879
    env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
796 880
}
797 881

  
882
static always_inline void set_HIT0_LO (uint64_t HILO)
883
{
884
    env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
885
    T0 = env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
886
}
887

  
888
static always_inline void set_HI_LOT0 (uint64_t HILO)
889
{
890
    T0 = env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
891
    env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
892
}
893

  
798 894
void op_mult (void)
799 895
{
800 896
    set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
......
842 938
    set_HILO(get_HILO() - tmp);
843 939
    FORCE_RET();
844 940
}
941

  
942
/* Multiplication variants of the vr54xx. */
943
void op_muls (void)
944
{
945
    set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
946
    FORCE_RET();
947
}
948

  
949
void op_mulsu (void)
950
{
951
    set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
952
    FORCE_RET();
953
}
954

  
955
void op_macc (void)
956
{
957
    set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
958
    FORCE_RET();
959
}
960

  
961
void op_macchi (void)
962
{
963
    set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
964
    FORCE_RET();
965
}
966

  
967
void op_maccu (void)
968
{
969
    set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
970
    FORCE_RET();
971
}
972

  
973
void op_macchiu (void)
974
{
975
    set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
976
    FORCE_RET();
977
}
978

  
979
void op_msac (void)
980
{
981
    set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
982
    FORCE_RET();
983
}
984

  
985
void op_msachi (void)
986
{
987
    set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
988
    FORCE_RET();
989
}
990

  
991
void op_msacu (void)
992
{
993
    set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
994
    FORCE_RET();
995
}
996

  
997
void op_msachiu (void)
998
{
999
    set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
1000
    FORCE_RET();
1001
}
1002

  
1003
void op_mulhi (void)
1004
{
1005
    set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
1006
    FORCE_RET();
1007
}
1008

  
1009
void op_mulhiu (void)
1010
{
1011
    set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
1012
    FORCE_RET();
1013
}
1014

  
1015
void op_mulshi (void)
1016
{
1017
    set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
1018
    FORCE_RET();
1019
}
1020

  
1021
void op_mulshiu (void)
1022
{
1023
    set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
1024
    FORCE_RET();
1025
}
1026

  
845 1027
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
846 1028

  
847 1029
#if defined(TARGET_MIPS64)
b/target-mips/op_helper.c
172 172
    env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
173 173
}
174 174

  
175
static always_inline void set_HIT0_LO (uint64_t HILO)
176
{
177
    env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
178
    T0 = env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
179
}
180

  
181
static always_inline void set_HI_LOT0 (uint64_t HILO)
182
{
183
    T0 = env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
184
    env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
185
}
186

  
175 187
void do_mult (void)
176 188
{
177 189
    set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
......
213 225
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
214 226
    set_HILO(get_HILO() - tmp);
215 227
}
216
#endif
228

  
229
/* Multiplication variants of the vr54xx. */
230
void do_muls (void)
231
{
232
    set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
233
}
234

  
235
void do_mulsu (void)
236
{
237
    set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
238
}
239

  
240
void do_macc (void)
241
{
242
    set_HI_LOT0(((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
243
}
244

  
245
void do_macchi (void)
246
{
247
    set_HIT0_LO(((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
248
}
249

  
250
void do_maccu (void)
251
{
252
    set_HI_LOT0(((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
253
}
254

  
255
void do_macchiu (void)
256
{
257
    set_HIT0_LO(((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
258
}
259

  
260
void do_msac (void)
261
{
262
    set_HI_LOT0(((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
263
}
264

  
265
void do_msachi (void)
266
{
267
    set_HIT0_LO(((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
268
}
269

  
270
void do_msacu (void)
271
{
272
    set_HI_LOT0(((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
273
}
274

  
275
void do_msachiu (void)
276
{
277
    set_HIT0_LO(((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
278
}
279

  
280
void do_mulhi (void)
281
{
282
    set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
283
}
284

  
285
void do_mulhiu (void)
286
{
287
    set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
288
}
289

  
290
void do_mulshi (void)
291
{
292
    set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
293
}
294

  
295
void do_mulshiu (void)
296
{
297
    set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
298
}
299
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
217 300

  
218 301
#if HOST_LONG_BITS < 64
219 302
void do_div (void)
b/target-mips/translate.c
214 214
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
215 215
};
216 216

  
217
/* Multiplication variants of the vr54xx. */
218
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
219

  
220
enum {
221
    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
222
    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
223
    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
224
    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
225
    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
226
    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
227
    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
228
    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
229
    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
230
    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
231
    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
232
    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
233
    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
234
    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
235
};
236

  
217 237
/* REGIMM (rt field) opcodes */
218 238
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
219 239

  
......
1530 1550
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1531 1551
}
1532 1552

  
1553
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
1554
                            int rd, int rs, int rt)
1555
{
1556
    const char *opn = "mul vr54xx";
1557

  
1558
    GEN_LOAD_REG_T0(rs);
1559
    GEN_LOAD_REG_T1(rt);
1560

  
1561
    switch (opc) {
1562
    case OPC_VR54XX_MULS:
1563
        gen_op_muls();
1564
        opn = "muls";
1565
	break;
1566
    case OPC_VR54XX_MULSU:
1567
        gen_op_mulsu();
1568
        opn = "mulsu";
1569
	break;
1570
    case OPC_VR54XX_MACC:
1571
        gen_op_macc();
1572
        opn = "macc";
1573
	break;
1574
    case OPC_VR54XX_MACCU:
1575
        gen_op_maccu();
1576
        opn = "maccu";
1577
	break;
1578
    case OPC_VR54XX_MSAC:
1579
        gen_op_msac();
1580
        opn = "msac";
1581
	break;
1582
    case OPC_VR54XX_MSACU:
1583
        gen_op_msacu();
1584
        opn = "msacu";
1585
	break;
1586
    case OPC_VR54XX_MULHI:
1587
        gen_op_mulhi();
1588
        opn = "mulhi";
1589
	break;
1590
    case OPC_VR54XX_MULHIU:
1591
        gen_op_mulhiu();
1592
        opn = "mulhiu";
1593
	break;
1594
    case OPC_VR54XX_MULSHI:
1595
        gen_op_mulshi();
1596
        opn = "mulshi";
1597
	break;
1598
    case OPC_VR54XX_MULSHIU:
1599
        gen_op_mulshiu();
1600
        opn = "mulshiu";
1601
	break;
1602
    case OPC_VR54XX_MACCHI:
1603
        gen_op_macchi();
1604
        opn = "macchi";
1605
	break;
1606
    case OPC_VR54XX_MACCHIU:
1607
        gen_op_macchiu();
1608
        opn = "macchiu";
1609
	break;
1610
    case OPC_VR54XX_MSACHI:
1611
        gen_op_msachi();
1612
        opn = "msachi";
1613
	break;
1614
    case OPC_VR54XX_MSACHIU:
1615
        gen_op_msachiu();
1616
        opn = "msachiu";
1617
	break;
1618
    default:
1619
        MIPS_INVAL("mul vr54xx");
1620
        generate_exception(ctx, EXCP_RI);
1621
        return;
1622
    }
1623
    GEN_STORE_T0_REG(rd);
1624
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1625
}
1626

  
1533 1627
static void gen_cl (DisasContext *ctx, uint32_t opc,
1534 1628
                    int rd, int rs)
1535 1629
{
......
5973 6067
            gen_arith(env, ctx, op1, rd, rs, rt);
5974 6068
            break;
5975 6069
        case OPC_MULT ... OPC_DIVU:
5976
            gen_muldiv(ctx, op1, rs, rt);
6070
            if (sa) {
6071
                check_insn(env, ctx, INSN_VR54XX);
6072
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6073
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6074
            } else
6075
                gen_muldiv(ctx, op1, rs, rt);
5977 6076
            break;
5978 6077
        case OPC_JR ... OPC_JALR:
5979 6078
            gen_compute_branch(ctx, op1, rs, rd, sa);
b/target-mips/translate_init.c
306 306
        .mmu_type = MMU_TYPE_R4000,
307 307
    },
308 308
    {
309
        .name = "VR5432",
310
        .CP0_PRid = 0x00005400,
311
        /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */
312
        .CP0_Config0 = (1 << 17) | (0x1 << 9) | (0x1 << 6) | (0x2 << CP0C0_K0),
313
        .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
314
        .SYNCI_Step = 16,
315
        .CCRes = 2,
316
        .CP0_Status_rw_bitmask = 0x3678FFFF,
317
        /* The VR5432 has a full 64bit FPU but doesn't use the fcr0 bits. */
318
        .CP1_fcr0 = (0x54 << FCR0_PRID) | (0x0 << FCR0_REV),
319
        .SEGBITS = 40,
320
        .PABITS = 32,
321
        .insn_flags = CPU_VR54XX,
322
        .mmu_type = MMU_TYPE_R4000,
323
    },
324
    {
309 325
        .name = "5Kc",
310 326
        .CP0_PRid = 0x00018100,
311 327
        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) |

Also available in: Unified diff