Commit e9c71dd1c1f5aeb3732261a02dcfae031973f053
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
Showing
6 changed files
with
405 additions
and
7 deletions
target-mips/exec.h
| @@ -79,6 +79,20 @@ void do_madd (void); | @@ -79,6 +79,20 @@ void do_madd (void); | ||
| 79 | void do_maddu (void); | 79 | void do_maddu (void); |
| 80 | void do_msub (void); | 80 | void do_msub (void); |
| 81 | void do_msubu (void); | 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 | #endif | 96 | #endif |
| 83 | #if defined(TARGET_MIPS64) | 97 | #if defined(TARGET_MIPS64) |
| 84 | void do_ddiv (void); | 98 | void do_ddiv (void); |
target-mips/mips-defs.h
| @@ -4,7 +4,7 @@ | @@ -4,7 +4,7 @@ | ||
| 4 | /* If we want to use host float regs... */ | 4 | /* If we want to use host float regs... */ |
| 5 | //#define USE_HOST_FLOAT_REGS | 5 | //#define USE_HOST_FLOAT_REGS |
| 6 | 6 | ||
| 7 | -/* real pages are variable size... */ | 7 | +/* Real pages are variable size... */ |
| 8 | #define TARGET_PAGE_BITS 12 | 8 | #define TARGET_PAGE_BITS 12 |
| 9 | #define MIPS_TLB_MAX 128 | 9 | #define MIPS_TLB_MAX 128 |
| 10 | 10 | ||
| @@ -29,7 +29,7 @@ | @@ -29,7 +29,7 @@ | ||
| 29 | #define ISA_MIPS64 0x00000080 | 29 | #define ISA_MIPS64 0x00000080 |
| 30 | #define ISA_MIPS64R2 0x00000100 | 30 | #define ISA_MIPS64R2 0x00000100 |
| 31 | 31 | ||
| 32 | -/* MIPS ASE */ | 32 | +/* MIPS ASEs. */ |
| 33 | #define ASE_MIPS16 0x00001000 | 33 | #define ASE_MIPS16 0x00001000 |
| 34 | #define ASE_MIPS3D 0x00002000 | 34 | #define ASE_MIPS3D 0x00002000 |
| 35 | #define ASE_MDMX 0x00004000 | 35 | #define ASE_MDMX 0x00004000 |
| @@ -38,19 +38,23 @@ | @@ -38,19 +38,23 @@ | ||
| 38 | #define ASE_MT 0x00020000 | 38 | #define ASE_MT 0x00020000 |
| 39 | #define ASE_SMARTMIPS 0x00040000 | 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 | #define CPU_MIPS1 (ISA_MIPS1) | 45 | #define CPU_MIPS1 (ISA_MIPS1) |
| 46 | #define CPU_MIPS2 (CPU_MIPS1 | ISA_MIPS2) | 46 | #define CPU_MIPS2 (CPU_MIPS1 | ISA_MIPS2) |
| 47 | #define CPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) | 47 | #define CPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) |
| 48 | #define CPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) | 48 | #define CPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) |
| 49 | +#define CPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) | ||
| 50 | + | ||
| 49 | #define CPU_MIPS5 (CPU_MIPS4 | ISA_MIPS5) | 51 | #define CPU_MIPS5 (CPU_MIPS4 | ISA_MIPS5) |
| 50 | 52 | ||
| 53 | +/* MIPS Technologies "Release 1" */ | ||
| 51 | #define CPU_MIPS32 (CPU_MIPS2 | ISA_MIPS32) | 54 | #define CPU_MIPS32 (CPU_MIPS2 | ISA_MIPS32) |
| 52 | #define CPU_MIPS64 (CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64) | 55 | #define CPU_MIPS64 (CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64) |
| 53 | 56 | ||
| 57 | +/* MIPS Technologies "Release 2" */ | ||
| 54 | #define CPU_MIPS32R2 (CPU_MIPS32 | ISA_MIPS32R2) | 58 | #define CPU_MIPS32R2 (CPU_MIPS32 | ISA_MIPS32R2) |
| 55 | #define CPU_MIPS64R2 (CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2) | 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,6 +781,90 @@ void op_msubu (void) | ||
| 781 | FORCE_RET(); | 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 | #else /* TARGET_LONG_BITS > HOST_LONG_BITS */ | 868 | #else /* TARGET_LONG_BITS > HOST_LONG_BITS */ |
| 785 | 869 | ||
| 786 | static always_inline uint64_t get_HILO (void) | 870 | static always_inline uint64_t get_HILO (void) |
| @@ -795,6 +879,18 @@ static always_inline void set_HILO (uint64_t HILO) | @@ -795,6 +879,18 @@ static always_inline void set_HILO (uint64_t HILO) | ||
| 795 | env->HI[0][env->current_tc] = (int32_t)(HILO >> 32); | 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 | void op_mult (void) | 894 | void op_mult (void) |
| 799 | { | 895 | { |
| 800 | set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); | 896 | set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); |
| @@ -842,6 +938,92 @@ void op_msubu (void) | @@ -842,6 +938,92 @@ void op_msubu (void) | ||
| 842 | set_HILO(get_HILO() - tmp); | 938 | set_HILO(get_HILO() - tmp); |
| 843 | FORCE_RET(); | 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 | #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ | 1027 | #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ |
| 846 | 1028 | ||
| 847 | #if defined(TARGET_MIPS64) | 1029 | #if defined(TARGET_MIPS64) |
target-mips/op_helper.c
| @@ -172,6 +172,18 @@ static always_inline void set_HILO (uint64_t HILO) | @@ -172,6 +172,18 @@ static always_inline void set_HILO (uint64_t HILO) | ||
| 172 | env->HI[0][env->current_tc] = (int32_t)(HILO >> 32); | 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 | void do_mult (void) | 187 | void do_mult (void) |
| 176 | { | 188 | { |
| 177 | set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); | 189 | set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); |
| @@ -213,7 +225,78 @@ void do_msubu (void) | @@ -213,7 +225,78 @@ void do_msubu (void) | ||
| 213 | tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); | 225 | tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); |
| 214 | set_HILO(get_HILO() - tmp); | 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 | #if HOST_LONG_BITS < 64 | 301 | #if HOST_LONG_BITS < 64 |
| 219 | void do_div (void) | 302 | void do_div (void) |
target-mips/translate.c
| @@ -214,6 +214,26 @@ enum { | @@ -214,6 +214,26 @@ enum { | ||
| 214 | OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, | 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 | /* REGIMM (rt field) opcodes */ | 237 | /* REGIMM (rt field) opcodes */ |
| 218 | #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16)) | 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,6 +1550,80 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, | ||
| 1530 | MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]); | 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 | static void gen_cl (DisasContext *ctx, uint32_t opc, | 1627 | static void gen_cl (DisasContext *ctx, uint32_t opc, |
| 1534 | int rd, int rs) | 1628 | int rd, int rs) |
| 1535 | { | 1629 | { |
| @@ -5973,7 +6067,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -5973,7 +6067,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
| 5973 | gen_arith(env, ctx, op1, rd, rs, rt); | 6067 | gen_arith(env, ctx, op1, rd, rs, rt); |
| 5974 | break; | 6068 | break; |
| 5975 | case OPC_MULT ... OPC_DIVU: | 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 | break; | 6076 | break; |
| 5978 | case OPC_JR ... OPC_JALR: | 6077 | case OPC_JR ... OPC_JALR: |
| 5979 | gen_compute_branch(ctx, op1, rs, rd, sa); | 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,6 +306,22 @@ static mips_def_t mips_defs[] = | ||
| 306 | .mmu_type = MMU_TYPE_R4000, | 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 | .name = "5Kc", | 325 | .name = "5Kc", |
| 310 | .CP0_PRid = 0x00018100, | 326 | .CP0_PRid = 0x00018100, |
| 311 | .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | | 327 | .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | |