Commit e9c71dd1c1f5aeb3732261a02dcfae031973f053

Authored by ths
1 parent 29fe0e34

Support for VR5432, and some of its special instructions. Original patch

by Dirk Behme.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3859 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/exec.h
... ... @@ -79,6 +79,20 @@ void do_madd (void);
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);
... ...
target-mips/mips-defs.h
... ... @@ -4,7 +4,7 @@
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,7 +29,7 @@
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,19 +38,23 @@
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  
... ...
target-mips/op.c
... ... @@ -781,6 +781,90 @@ void op_msubu (void)
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,6 +879,18 @@ static always_inline void set_HILO (uint64_t HILO)
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,6 +938,92 @@ void op_msubu (void)
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)
... ...
target-mips/op_helper.c
... ... @@ -172,6 +172,18 @@ static always_inline void set_HILO (uint64_t HILO)
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,7 +225,78 @@ void do_msubu (void)
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)
... ...
target-mips/translate.c
... ... @@ -214,6 +214,26 @@ enum {
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,6 +1550,80 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
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,7 +6067,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
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);
... ...
target-mips/translate_init.c
... ... @@ -306,6 +306,22 @@ static mips_def_t mips_defs[] =
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) |
... ...