From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25686 invoked by alias); 9 Oct 2002 14:14:49 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 25678 invoked from network); 9 Oct 2002 14:14:47 -0000 Received: from unknown (HELO executor.cambridge.redhat.com) (195.224.55.237) by sources.redhat.com with SMTP; 9 Oct 2002 14:14:47 -0000 Received: from talisman.cambridge.redhat.com (talisman.cambridge.redhat.com [172.16.18.81]) by executor.cambridge.redhat.com (Postfix) with ESMTP id C84A4ABAFC; Wed, 9 Oct 2002 15:14:46 +0100 (BST) Received: (from rsandifo@localhost) by talisman.cambridge.redhat.com (8.11.6/8.11.0) id g99EEhc22541; Wed, 9 Oct 2002 15:14:43 +0100 X-Authentication-Warning: talisman.cambridge.redhat.com: rsandifo set sender to rsandifo@redhat.com using -f To: cgd@broadcom.com Cc: gdb-patches@sources.redhat.com Subject: Re: sim/mips patch: add support for more NEC VR targets References: From: Richard Sandiford Date: Wed, 09 Oct 2002 07:14:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-10/txt/msg00207.txt.bz2 Thanks for the review. cgd@broadcom.com writes: > > - The existing vr5000 model selects three-address mult > > and dmult instructions, but those instructions aren't > > listed in NEC's documentation. There's a three-address > > vr5400 mult instruction, but it has a different opcode. > > > > The vr5000 model only seems to exist for these instructions, > > it would otherwise be a standard mipsIV target. Would it > > be OK to submit a follow-on patch to remove it? > > Well, there are a couple of other differences w.r.t: BC0T, DMFC0, > DMTC0, COPz... But I don't know whether they're relevant. Good catch. I checked that vr5000 implied mipsIV, but not the other way around (duh!). Anyway, the processor doesn't have bc0f, bc0t, or a coprocessor 2, so raising a reserved instruction exception is the right thing to do. But I guess that's true of many targets, and AFAICT the exception is raised regardless of whether a target is listed under BC0F, BC0T or COPz. So I think it's safe to "add" vr5000 here. According to the manual, dmtc0 and dmfc0 are supported. I can't check on real hardware at the moment, but I've no reason to doubt them. So it seems removing vr5000 would actually be a bug fix ;) > > - The uses of vr4100 in mips.igen seem to be redundant > > with mipsIII. OK to remove them as well? > > I am concerned w/ one thing here, though: > > vr4100 selects a bunch of different cop1 instructions than mipsIII > does, e.g. CFC1a vs. CFC1b. Yeah. I don't understand why, really, since the vr41xx processors don't have an FPU. Maybe the target environment was assumed to provide an emulator or something? But key instructions (like bc1f and bc1t ;-) are missing, so very little FP code is going to work. > > I'm planning to submit more 4120 patches to FSF GCC soon. In the > > meantime, the patch was tested against the NEC GNUPro version. Wasn't very clear, but... > I assume that means that this was tested in the current gdb+sim > sources, against that version of GNUpro. ...yes, that's right. > There are a couple of specific things that would be nice if you could > arrange in follow-on patches, in addition to what you describe above: > > * it would be good if things like vr_run.c could be automatically > generated. OK. Guilt at my earlier lameness forced me to give this a go. New version attached. Not pretty (and I didn't use awk ;-) but it should reduce the amount of cut&paste if other targets use MULTI. I've also removed the need to define sim_multi_filter and sim_multi_machine, since igen can cope with the same machine & filter being given twice. > > *************** > > *** 1010,1015 **** > > --- 1016,1022 ---- > > "clo r, r" > > *mips32: > > *mips64: > > + *vr5500: > > (and the related instructions) > > You might check that the 5500 actually uses the same encodings here, > and what it says about unpredicable operation if RT != RD. (this is > coded based on the MIPS32/MIPS64 specs, which accomodate an older > implementation which used the other reg. than mips32/mips64 did.) Just to confirm it and the other insns do have the same encoding. As for RT & RD, the preliminary data sheet just says "Specify the same register as general-purpose register rd for general-purpose register rt." So I think it's fair for the simulator to complain if they're different. > There is an annoying interaction between multi-arching a sim and using > STATE_ARCHITECTURE (SD)->mach: e.g. if you have the thing above where > you check bfd_mach_mips5500, if mips5500 is the 'default' for your sim > (i.e., catches unknown machine types), that check will fail. > > Really, we need to be sure to check and, if necessary, set 'mach' to a > default value when it is set. Where do you think this should happen? In sim_engine_run()? Anyway, patch with new configuration attached. Tested in the same way as before. igen/ * gen-engine.c (print_engine_issue_prefix_hook): Don't add the global prefix to ENGINE_ISSUE_PREFIX_HOOK. (print_engine_issue_postfix_hook): Likewise ENGINE_ISSUE_POSTFIX_HOOK. mips/ * configure.in (mips64vr*): Define TARGET_ENABLE_FR to 1. (mips64vr-*-*, mips64vrel-*-*): New configurations. Add a new simulator generator, MULTI. * configure: Regenerate. * Makefile.in (SIM_MULTI_OBJ, SIM_MULTI_ALL, SIM_MULTI_CONFIGS): New. (BUILT_SRC_FROM_MULTI): New. Depend on tmp-multi. (tmp-mach-multi, tmp-itable-multi, tmp-run-multi): New dependencies. (tmp-multi): Combine them. (clean-extra): Remove sources in BUILT_SRC_FROM_MULTI. * sim-main.h: Include bfd.h. * mips.igen (vr4120, vr5400, vr5500): New models. (check_mf_cycles): Don't enforce mflo and mfhi separation in vr5500 code. (clo, clz, dclo, dclz, madd, maddu, msub, msub, mul): Add *vr5500. * vr.igen: Replace with new version. * multi_run.c: New file. Index: igen/gen-engine.c =================================================================== RCS file: /cvs/src/src/sim/igen/gen-engine.c,v retrieving revision 1.2 diff -c -d -p -r1.2 gen-engine.c *** igen/gen-engine.c 3 Jun 2002 16:04:31 -0000 1.2 --- igen/gen-engine.c 9 Oct 2002 09:14:27 -0000 *************** print_engine_issue_prefix_hook (lf *file *** 41,50 **** { lf_printf (file, "\n"); lf_indent_suppress (file); ! lf_printf (file, "#if defined (%sENGINE_ISSUE_PREFIX_HOOK)\n", ! options.module.global.prefix.l); ! lf_printf (file, "%sENGINE_ISSUE_PREFIX_HOOK();\n", ! options.module.global.prefix.l); lf_indent_suppress (file); lf_printf (file, "#endif\n"); lf_printf (file, "\n"); --- 41,48 ---- { lf_printf (file, "\n"); lf_indent_suppress (file); ! lf_printf (file, "#if defined (ENGINE_ISSUE_PREFIX_HOOK)\n"); ! lf_printf (file, "ENGINE_ISSUE_PREFIX_HOOK();\n"); lf_indent_suppress (file); lf_printf (file, "#endif\n"); lf_printf (file, "\n"); *************** print_engine_issue_postfix_hook (lf *fil *** 55,64 **** { lf_printf (file, "\n"); lf_indent_suppress (file); ! lf_printf (file, "#if defined (%sENGINE_ISSUE_POSTFIX_HOOK)\n", ! options.module.global.prefix.l); ! lf_printf (file, "%sENGINE_ISSUE_POSTFIX_HOOK();\n", ! options.module.global.prefix.l); lf_indent_suppress (file); lf_printf (file, "#endif\n"); lf_printf (file, "\n"); --- 53,60 ---- { lf_printf (file, "\n"); lf_indent_suppress (file); ! lf_printf (file, "#if defined (ENGINE_ISSUE_POSTFIX_HOOK)\n"); ! lf_printf (file, "ENGINE_ISSUE_POSTFIX_HOOK();\n"); lf_indent_suppress (file); lf_printf (file, "#endif\n"); lf_printf (file, "\n"); Index: mips/configure.in =================================================================== RCS file: /cvs/src/src/sim/mips/configure.in,v retrieving revision 1.4 diff -c -d -p -r1.4 configure.in *** mips/configure.in 14 Jun 2002 18:49:09 -0000 1.4 --- mips/configure.in 9 Oct 2002 09:14:27 -0000 *************** SIM_AC_OPTION_WARNINGS *** 18,23 **** --- 18,24 ---- # in question. # case "${target}" in + mips64vr*-*-*) SIM_SUBTARGET="-DTARGET_ENABLE_FR=1" ;; mips*tx39*) SIM_SUBTARGET="-DSUBTARGET_R3900=1";; mipsisa32*-*-*) SIM_SUBTARGET="-DTARGET_ENABLE_FR=1";; mipsisa64*-*-*) SIM_SUBTARGET="-DTARGET_ENABLE_FR=1";; *************** case "${target}" in *** 117,122 **** --- 118,132 ---- sim_igen_filter="32,64,f" sim_m16_filter="16" ;; + mips64vr-*-* | mips64vrel-*-*) + sim_gen=MULTI + sim_multi_arch_configs="\ + vr4100:mipsIII,mips16,vr4100:32,64@4100,4111 \ + vr4120:mipsIII,mips16,vr4120:32,64@4120 \ + vr5000:mipsIV:32,64,f@4300,5000,default \ + vr5400:mipsIV,vr5400:32,64,f@5400 \ + vr5500:mipsIV,vr5500:32,64,f@5500" + ;; mips64*-*-*) sim_igen_filter="32,64,f" sim_gen=IGEN ;; *************** case "${target}" in *** 146,156 **** --- 156,239 ---- sim_igen_filter="32,f" ;; esac + + # The MULTI generator can combine several simulation engines into + # one executable. A configuration which uses the MULTI should + # set ${sim_multi_arch_configs} to the list of engines to build. + # Each space-separated entry has the form NAME:MACHINE:FILTER@ARCHS, + # where: + # + # - NAME is a C-compatible prefix for the engine, + # - MACHINE is a -M argument, + # - FILTER is a -F argument, and + # - ARCHS is a comma-separated list of bfd machines that the + # simulator can run. + # + # Each entry will have a separate simulation engine whose prefix is + # m32. If the machine list includes "mips16", there will also + # be a mips16 engine, prefix m16. The mips16 engine will be + # generated using the same machine list as the 32-bit version, + # but the filter will be "16" instead of FILTER. + # + # The simulator compares the bfd mach against ARCHS to decide + # which engine to use. Entries in ARCHS can be a bfd_mach_mips* + # value with "bfd_mach_mips" removed, or the special string + # "default" to indicate that a particular engine should be + # the default. + if test ${sim_gen} = MULTI; then + rm -f multi-include.h multi-switch.c + sim_multi_flags= + sim_multi_obj=multi_run.o + for fc in ${sim_multi_arch_configs}; do + c=`echo ${fc} | sed 's/@.*//'` + archs=`echo ${fc} | sed 's/.*@//'` + name=`echo ${c} | sed 's/:.*//'` + m=`echo ${c} | sed 's/.*:\(.*\):.*/\1/'` + f=`echo ${c} | sed 's/.*://'` + sim_multi_flags="${sim_multi_flags} -F ${f} -M ${m}" + case $c in + *:*mips16*:*) + ws="m32 m16" + sim_multi_src="${sim_multi_src} m16${name}_run.c" + sim_multi_obj="${sim_multi_obj} m16${name}_run.o" + sim_multi_flags="${sim_multi_flags} -F 16" + ;; + *) + ws=m32 + ;; + esac + for w in ${ws}; do + for base in engine icache idecode model semantics support; do + sim_multi_src="${sim_multi_src} ${w}${name}_${base}.c" + sim_multi_src="${sim_multi_src} ${w}${name}_${base}.h" + sim_multi_obj="${sim_multi_obj} ${w}${name}_${base}.o" + done + sim_multi_configs="${sim_multi_configs} ${w}${c}" + done + echo "#include \"${w}${name}_engine.h\"" >> multi-include.h + for a in `echo $archs | sed 's/,/ /g'`; do + case $a in + default) echo "default:" >> multi-switch.c ;; + *) echo "case bfd_mach_mips$a:" >> multi-switch.c ;; + esac + done + echo " ${w}${name}_engine_run (sd, next_cpu_nr, nr_cpus, signal);" \ + >> multi-switch.c + echo " break;" >> multi-switch.c + done + else + # For clean-extra + sim_multi_src=doesnt-exist.c + fi sim_igen_flags="-F ${sim_igen_filter} ${sim_igen_machine} ${sim_igen_smp}" sim_m16_flags=" -F ${sim_m16_filter} ${sim_m16_machine} ${sim_igen_smp}" AC_SUBST(sim_igen_flags) AC_SUBST(sim_m16_flags) AC_SUBST(sim_gen) + AC_SUBST(sim_multi_flags) + AC_SUBST(sim_multi_configs) + AC_SUBST(sim_multi_src) + AC_SUBST(sim_multi_obj) # Index: mips/Makefile.in =================================================================== RCS file: /cvs/src/src/sim/mips/Makefile.in,v retrieving revision 1.7 diff -c -d -p -r1.7 Makefile.in *** mips/Makefile.in 14 Jun 2002 18:49:09 -0000 1.7 --- mips/Makefile.in 9 Oct 2002 09:14:27 -0000 *************** SIM_M16_OBJ = \ *** 33,38 **** --- 33,39 ---- itable.o \ m16run.o \ + SIM_MULTI_OBJ = itable.o @sim_multi_obj@ MIPS_EXTRA_OBJS = @mips_extra_objs@ MIPS_EXTRA_LIBS = @mips_extra_libs@ *************** BUILT_SRC_FROM_GEN = \ *** 98,103 **** --- 99,105 ---- SIM_IGEN_ALL = tmp-igen SIM_M16_ALL = tmp-m16 + SIM_MULTI_ALL = tmp-multi $(BUILT_SRC_FROM_GEN): $(SIM_@sim_gen@_ALL) *************** tmp-m16: $(IGEN_INSN) $(IGEN_DC) ../igen *** 291,300 **** --- 293,389 ---- touch tmp-m16 + BUILT_SRC_FROM_MULTI = @sim_multi_src@ + SIM_MULTI_CONFIGS = @sim_multi_configs@ + + $(BUILT_SRC_FROM_MULTI): tmp-multi + tmp-multi: tmp-mach-multi tmp-itable-multi tmp-run-multi targ-vals.h + tmp-mach-multi: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE) + for t in $(SIM_MULTI_CONFIGS); do \ + p=`echo $${t} | sed -e 's/:.*//'` ; \ + m=`echo $${t} | sed -e 's/.*:\(.*\):.*/\1/'` ; \ + f=`echo $${t} | sed -e 's/.*://'` ; \ + case $${p} in \ + m16*) e="-B 16 -H 15 -o $(M16_DC) -F 16" ;; \ + *) e="-B 32 -H 31 -o $(IGEN_DC) -F $${f}" ;; \ + esac; \ + ../igen/igen \ + $(IGEN_TRACE) \ + $${e} \ + -I $(srcdir) \ + -Werror \ + -Wnodiscard \ + -N 0 \ + -M $${m} \ + -G gen-direct-access \ + -G gen-zero-r0 \ + -i $(IGEN_INSN) \ + -P $${p}_ \ + -x \ + -n $${p}_icache.h -hc tmp-icache.h \ + -n $${p}_icache.c -c tmp-icache.c \ + -n $${p}_semantics.h -hs tmp-semantics.h \ + -n $${p}_semantics.c -s tmp-semantics.c \ + -n $${p}_idecode.h -hd tmp-idecode.h \ + -n $${p}_idecode.c -d tmp-idecode.c \ + -n $${p}_model.h -hm tmp-model.h \ + -n $${p}_model.c -m tmp-model.c \ + -n $${p}_support.h -hf tmp-support.h \ + -n $${p}_support.c -f tmp-support.c \ + -n $${p}_engine.h -he tmp-engine.h \ + -n $${p}_engine.c -e tmp-engine.c \ + ; \ + $(srcdir)/../../move-if-change tmp-icache.h $${p}_icache.h ; \ + $(srcdir)/../../move-if-change tmp-icache.c $${p}_icache.c ; \ + $(srcdir)/../../move-if-change tmp-idecode.h $${p}_idecode.h ; \ + $(srcdir)/../../move-if-change tmp-idecode.c $${p}_idecode.c ; \ + $(srcdir)/../../move-if-change tmp-semantics.h $${p}_semantics.h ; \ + $(srcdir)/../../move-if-change tmp-semantics.c $${p}_semantics.c ; \ + $(srcdir)/../../move-if-change tmp-model.h $${p}_model.h ; \ + $(srcdir)/../../move-if-change tmp-model.c $${p}_model.c ; \ + $(srcdir)/../../move-if-change tmp-support.h $${p}_support.h ; \ + $(srcdir)/../../move-if-change tmp-support.c $${p}_support.c ; \ + $(srcdir)/../../move-if-change tmp-engine.h $${p}_engine.h ; \ + $(srcdir)/../../move-if-change tmp-engine.c $${p}_engine.c ; \ + done + touch tmp-mach-multi + tmp-itable-multi: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE) + ../igen/igen \ + $(IGEN_TRACE) \ + -I $(srcdir) \ + -Werror \ + -Wnodiscard \ + -Wnowidth \ + -N 0 \ + @sim_multi_flags@ \ + -G gen-direct-access \ + -G gen-zero-r0 \ + -i $(IGEN_INSN) \ + -n itable.h -ht tmp-itable.h \ + -n itable.c -t tmp-itable.c \ + # + $(srcdir)/../../move-if-change tmp-itable.h itable.h + $(srcdir)/../../move-if-change tmp-itable.c itable.c + touch tmp-itable-multi + tmp-run-multi: $(srcdir)/m16run.c + for t in $(SIM_MULTI_CONFIGS); do \ + case $${t} in \ + *:*mips16*:*) \ + m=`echo $${t} | sed -e 's/^m16//' -e 's/:.*//'`; \ + sed < $(srcdir)/m16run.c > tmp-run \ + -e "s/^sim_/m16$${m}_/" \ + -e "s/m16_/m16$${m}_/" \ + -e "s/m32_/m32$${m}_/" ; \ + $(srcdir)/../../move-if-change tmp-run m16$${m}_run.c ; \ + esac \ + done + touch tmp-run-multi + clean-extra: rm -f $(BUILT_SRC_FROM_GEN) rm -f $(BUILT_SRC_FROM_IGEN) rm -f $(BUILT_SRC_FROM_M16) + rm -f $(BUILT_SRC_FROM_MULTI) rm -f tmp-* rm -f m16*.o m32*.o itable*.o Index: mips/sim-main.h =================================================================== RCS file: /cvs/src/src/sim/mips/sim-main.h,v retrieving revision 1.23 diff -c -d -p -r1.23 sim-main.h *** mips/sim-main.h 14 Jun 2002 18:49:09 -0000 1.23 --- mips/sim-main.h 9 Oct 2002 09:14:27 -0000 *************** mips_core_signal ((SD), (CPU), (CIA), (M *** 41,47 **** typedef address_word sim_cia; #include "sim-base.h" ! /* Deprecated macros and types for manipulating 64bit values. Use ../common/sim-bits.h and ../common/sim-endian.h macros instead. */ --- 41,47 ---- typedef address_word sim_cia; #include "sim-base.h" ! #include "bfd.h" /* Deprecated macros and types for manipulating 64bit values. Use ../common/sim-bits.h and ../common/sim-endian.h macros instead. */ Index: mips/mips.igen =================================================================== RCS file: /cvs/src/src/sim/mips/mips.igen,v retrieving revision 1.49 diff -c -d -p -r1.49 mips.igen *** mips/mips.igen 31 Jul 2002 05:44:54 -0000 1.49 --- mips/mips.igen 9 Oct 2002 09:14:27 -0000 *************** *** 55,61 **** --- 55,64 ---- // (or which pre-date or use different encodings than the standard // instructions) are (for the most part) in separate .igen files. :model:::vr4100:mips4100: // vr.igen + :model:::vr4120:mips4120: :model:::vr5000:mips5000: + :model:::vr5400:mips5400: + :model:::vr5500:mips5500: :model:::r3900:mips3900: // tx.igen // MIPS Application Specific Extensions (ASEs) *************** *** 229,234 **** --- 232,240 ---- :function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new { + /* There are no timing requirements in vr5500 code. */ + if (STATE_ARCHITECTURE (SD)->mach == bfd_mach_mips5500) + return 1; if (history->mf.timestamp + 3 > time) { sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n", *************** *** 1010,1015 **** --- 1016,1022 ---- "clo r, r" *mips32: *mips64: + *vr5500: { unsigned32 temp = GPR[RS]; unsigned32 i, mask; *************** *** 1034,1039 **** --- 1041,1047 ---- "clz r, r" *mips32: *mips64: + *vr5500: { unsigned32 temp = GPR[RS]; unsigned32 i, mask; *************** *** 1143,1148 **** --- 1151,1157 ---- 011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO "dclo r, r" *mips64: + *vr5500: { unsigned64 temp = GPR[RS]; unsigned32 i; *************** *** 1166,1171 **** --- 1175,1181 ---- 011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ "dclz r, r" *mips64: + *vr5500: { unsigned64 temp = GPR[RS]; unsigned32 i; *************** *** 2189,2194 **** --- 2199,2205 ---- "madd r, r" *mips32: *mips64: + *vr5500: { signed64 temp; check_mult_hilo (SD_, HIHISTORY, LOHISTORY); *************** *** 2208,2213 **** --- 2219,2225 ---- "maddu r, r" *mips32: *mips64: + *vr5500: { unsigned64 temp; check_mult_hilo (SD_, HIHISTORY, LOHISTORY); *************** *** 2312,2317 **** --- 2324,2330 ---- "msub r, r" *mips32: *mips64: + *vr5500: { signed64 temp; check_mult_hilo (SD_, HIHISTORY, LOHISTORY); *************** *** 2331,2336 **** --- 2344,2350 ---- "msubu r, r" *mips32: *mips64: + *vr5500: { unsigned64 temp; check_mult_hilo (SD_, HIHISTORY, LOHISTORY); *************** *** 2388,2393 **** --- 2402,2408 ---- "mul r, r, r" *mips32: *mips64: + *vr5500: { signed64 prod; if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT])) Index: mips/vr.igen =================================================================== RCS file: /cvs/src/src/sim/mips/vr.igen,v retrieving revision 1.1.1.1 diff -c -d -p -r1.1.1.1 vr.igen *** mips/vr.igen 16 Apr 1999 01:35:07 -0000 1.1.1.1 --- mips/vr.igen 9 Oct 2002 09:14:27 -0000 *************** *** 3,78 **** // NEC specific instructions // ! // Integer Instructions ! // -------------------- ! // ! // MulAcc is the Multiply Accumulator. ! // This register is mapped on the the HI and LO registers. ! // Upper 32 bits of MulAcc is mapped on to lower 32 bits of HI register. ! // Lower 32 bits of MulAcc is mapped on to lower 32 bits of LO register. ! :function:::unsigned64:MulAcc: ! *vr4100: { ! unsigned64 result = U8_4 (HI, LO); ! return result; } ! :function:::void:SET_MulAcc:unsigned64 value ! *vr4100: { ! /* 64 bit specific */ ! *AL4_8 (&HI) = VH4_8 (value); ! *AL4_8 (&LO) = VL4_8 (value); } ! :function:::signed64:SignedMultiply:signed32 l, signed32 r ! *vr4100: { ! signed64 result = (signed64) l * (signed64) r; return result; } ! :function:::unsigned64:UnsignedMultiply:unsigned32 l, unsigned32 r ! *vr4100: { ! unsigned64 result = (unsigned64) l * (unsigned64) r; return result; } ! :function:::unsigned64:Low32Bits:unsigned64 value *vr4100: { ! unsigned64 result = (signed64) (signed32) VL4_8 (value); ! return result; } ! :function:::unsigned64:High32Bits:unsigned64 value *vr4100: { ! unsigned64 result = (signed64) (signed32) VH4_8 (value); ! return result; } ! // Multiply, Accumulate ! 000000,5.RS,5.RT,00000,00000,101000::64::MAC ! "mac r, r" ! *vr4100: { ! SET_MulAcc (SD_, MulAcc (SD_) + SignedMultiply (SD_, GPR[RS], GPR[RT])); } ! // D-Multiply, Accumulate ! 000000,5.RS,5.RT,00000,00000,101001::64::DMAC ! "dmac r, r" ! *vr4100: { ! LO = LO + SignedMultiply (SD_, GPR[RS], GPR[RT]); } --- 3,323 ---- // NEC specific instructions // ! :%s::::MFHI:int hi ! { ! return hi ? "hi" : ""; ! } + :%s::::SAT:int s + { + return s ? "s" : ""; + } ! :%s::::UNS:int u { ! return u ? "u" : ""; } ! // Simulate the various kinds of multiply and multiply-accumulate instructions. ! // Perform an operation of the form: ! // ! // LHS (+/-) GPR[RS] * GPR[RT] ! // ! // and store it in the 64-bit accumulator. Optionally copy either LO or ! // HI into a general purpose register. ! // ! // - RD is the destination register of the LO or HI move ! // - RS are RT are the multiplication source registers ! // - ACCUMULATE_P is true if LHS should be the value of the 64-bit accumulator, ! // false if it should be 0. ! // - STORE_HI_P is true if HI should be stored in RD, false if LO should be. ! // - UNSIGNED_P is true if the operation should be unsigned. ! // - SATURATE_P is true if the result should be saturated to a 32-bit value. ! // - SUBTRACT_P is true if the right hand side should be subtraced from LHS, ! // false if it should be added. ! // - SHORT_P is true if RS and RT must be 16-bit numbers. ! // - DOUBLE_P is true if the 64-bit accumulator is in LO, false it is a ! // concatenation of the low 32 bits of HI and LO. ! :function:::void:do_vr_mul_op:int rd, int rs, int rt, int accumulate_p, int store_hi_p, int unsigned_p, int saturate_p, int subtract_p, int short_p, int double_p { ! unsigned64 lhs, x, y, xcut, ycut, product, result; ! ! check_mult_hilo (SD_, HIHISTORY, LOHISTORY); ! ! lhs = (!accumulate_p ? 0 : double_p ? LO : U8_4 (HI, LO)); ! x = GPR[rs]; ! y = GPR[rt]; ! ! /* Work out the canonical form of X and Y from their significant bits. */ ! if (!short_p) ! { ! /* Normal sign-extension rule for 32-bit operands. */ ! xcut = EXTEND32 (x); ! ycut = EXTEND32 (y); ! } ! else if (unsigned_p) ! { ! /* Operands must be zero-extended 16-bit numbers. */ ! xcut = x & 0xffff; ! ycut = y & 0xffff; ! } ! else ! { ! /* Likewise but sign-extended. */ ! xcut = EXTEND16 (x); ! ycut = EXTEND16 (y); ! } ! if (x != xcut || y != ycut) ! sim_engine_abort (SD, CPU, CIA, ! "invalid multiplication operand at 0x%08lx\n", ! (long) CIA); ! ! TRACE_ALU_INPUT2 (x, y); ! product = (unsigned_p ? x * y : EXTEND32 (x) * EXTEND32 (y)); ! result = (subtract_p ? lhs - product : lhs + product); ! if (saturate_p) ! { ! /* Saturate the result to 32 bits. An unsigned, unsaturated ! result is zero-extended to 64 bits, but unsigned overflow ! causes all 64 bits to be set. */ ! if (!unsigned_p && (unsigned64) EXTEND32 (result) != result) ! result = ((signed64) result < 0 ? -0x7fffffff - 1 : 0x7fffffff); ! else if (unsigned_p && (result >> 32) != 0) ! result = (unsigned64) 0 - 1; ! } ! TRACE_ALU_RESULT (result); ! ! if (double_p) ! LO = result; ! else ! { ! LO = EXTEND32 (result); ! HI = EXTEND32 (VH4_8 (result)); ! } ! if (rd != 0) ! GPR[rd] = store_hi_p ? HI : LO; } ! // 32-bit rotate right of X by Y bits. ! :function:::unsigned64:do_ror:unsigned32 x,unsigned32 y ! *vr5400: ! *vr5500: { ! unsigned64 result; ! ! y &= 31; ! TRACE_ALU_INPUT2 (x, y); ! result = EXTEND32 (ROTR32 (x, y)); ! TRACE_ALU_RESULT (result); return result; } ! // Likewise 64-bit ! :function:::unsigned64:do_dror:unsigned64 x,unsigned64 y ! *vr5400: ! *vr5500: { ! unsigned64 result; ! ! y &= 63; ! TRACE_ALU_INPUT2 (x, y); ! result = ROTR64 (x, y); ! TRACE_ALU_RESULT (result); return result; } ! ! // VR4100 instructions. ! ! 000000,5.RS,5.RT,00000,00000,101000::32::MADD16 ! "madd16 r, r" *vr4100: { ! do_vr_mul_op (SD_, 0, RS, RT, ! 1 /* accumulate */, ! 0 /* store in LO */, ! 0 /* signed arithmetic */, ! 0 /* don't saturate */, ! 0 /* don't subtract */, ! 1 /* short */, ! 0 /* single */); } ! 000000,5.RS,5.RT,00000,00000,101001::64::DMADD16 ! "dmadd16 r, r" *vr4100: { ! do_vr_mul_op (SD_, 0, RS, RT, ! 1 /* accumulate */, ! 0 /* store in LO */, ! 0 /* signed arithmetic */, ! 0 /* don't saturate */, ! 0 /* don't subtract */, ! 1 /* short */, ! 1 /* double */); } ! // VR4120 and VR4130 instructions. ! ! 000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101001::64::DMACC ! "dmacc%s%s%s r, r, r" ! *vr4120: { ! do_vr_mul_op (SD_, RD, RS, RT, ! 1 /* accumulate */, ! MFHI, UNS, SAT, ! 0 /* don't subtract */, ! SAT /* short */, ! 1 /* double */); ! } ! ! 000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101000::32::MACC_4120 ! "macc%s%s%s r, r, r" ! *vr4120: ! { ! do_vr_mul_op (SD_, RD, RS, RT, ! 1 /* accumulate */, ! MFHI, UNS, SAT, ! 0 /* don't subtract */, ! SAT /* short */, ! 0 /* single */); } ! // VR5400 and VR5500 instructions. ! ! 000000,5.RS,5.RT,5.RD,0,1.MFHI,001,01100,1.UNS::32::MUL ! "mul%s%s r, r, r" ! *vr5400: ! *vr5500: { ! do_vr_mul_op (SD_, RD, RS, RT, ! 0 /* don't accumulate */, ! MFHI, UNS, ! 0 /* don't saturate */, ! 0 /* don't subtract */, ! 0 /* not short */, ! 0 /* single */); ! } ! ! 000000,5.RS,5.RT,5.RD,0,1.MFHI,011,01100,1.UNS::32::MULS ! "muls%s%s r, r, r" ! *vr5400: ! *vr5500: ! { ! do_vr_mul_op (SD_, RD, RS, RT, ! 0 /* don't accumulate */, ! MFHI, UNS, ! 0 /* don't saturate */, ! 1 /* subtract */, ! 0 /* not short */, ! 0 /* single */); ! } ! ! 000000,5.RS,5.RT,5.RD,0,1.MFHI,101,01100,1.UNS::32::MACC_5xxx ! "macc%s%s r, r, r" ! *vr5400: ! *vr5500: ! { ! do_vr_mul_op (SD_, RD, RS, RT, ! 1 /* accumulate */, ! MFHI, UNS, ! 0 /* don't saturate */, ! 0 /* don't subtract */, ! 0 /* not short */, ! 0 /* single */); ! } ! ! 000000,5.RS,5.RT,5.RD,0,1.MFHI,111,01100,1.UNS::32::MSAC ! "msac%s%s r, r, r" ! *vr5400: ! *vr5500: ! { ! do_vr_mul_op (SD_, RD, RS, RT, ! 1 /* accumulate */, ! MFHI, UNS, ! 0 /* don't saturate */, ! 1 /* subtract */, ! 0 /* not short */, ! 0 /* single */); ! } ! ! 000000,00001,5.RT,5.RD,5.SHIFT,000010::32::ROR ! "ror r, r, " ! *vr5400: ! *vr5500: ! { ! GPR[RD] = do_ror (SD_, GPR[RT], SHIFT); ! } ! ! 000000,5.RS,5.RT,5.RD,00001,000110::32::RORV ! "rorv r, r, r" ! *vr5400: ! *vr5500: ! { ! GPR[RD] = do_ror (SD_, GPR[RT], GPR[RS]); ! } ! ! 000000,00001,5.RT,5.RD,5.SHIFT,111010::64::DROR ! "dror r, r, " ! *vr5400: ! *vr5500: ! { ! GPR[RD] = do_dror (SD_, GPR[RT], SHIFT); ! } ! ! 000000,00001,5.RT,5.RD,5.SHIFT,111110::64::DROR32 ! "dror32 r, r, " ! *vr5400: ! *vr5500: ! { ! GPR[RD] = do_dror (SD_, GPR[RT], SHIFT + 32); ! } ! ! 000000,5.RS,5.RT,5.RD,00001,010110::64::DRORV ! "drorv r, r, r" ! *vr5400: ! *vr5500: ! { ! GPR[RD] = do_dror (SD_, GPR[RT], GPR[RS]); ! } ! ! 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64::LUXC1 ! "luxc1 f, r(r)" ! *vr5500: ! { ! check_fpu (SD_); ! COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, ! (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0)); ! } ! ! 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64::SUXC1 ! "suxc1 f, r(r)" ! *vr5500: ! { ! check_fpu (SD_); ! do_store (SD_, AccessLength_DOUBLEWORD, ! (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0, ! COP_SD (1, FS)); } + 010000,1,19.*,100000:COP0:32::WAIT + "wait" + *vr5500: + + 011100,00000,5.RT,5.DR,00000,111101:SPECIAL:64::MFDR + "mfdr r, r" + *vr5400: + *vr5500: + 011100,00100,5.RT,5.DR,00000,111101:SPECIAL:64::MTDR + "mtdr r, r" + *vr5400: + *vr5500: + 011100,00000,00000,00000,00000,111110:SPECIAL:64::DRET + "dret" + *vr5400: + *vr5500: *** /dev/null Tue Nov 14 21:44:43 2000 --- mips/multi_run.c Tue Oct 8 14:43:29 2002 *************** *** 0 **** --- 1,43 ---- + /* Main entry point for MULTI simulators. + Copyright (C) 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + + #include "sim-main.h" + #include "multi-include.h" + + #define SD sd + #define CPU cpu + + void + sim_engine_run (SIM_DESC sd, + int next_cpu_nr, + int nr_cpus, + int signal) /* ignore */ + { + int mach, i; + + if (STATE_ARCHITECTURE (sd) == NULL) + mach = 0; + else + mach = STATE_ARCHITECTURE (sd)->mach; + + switch (mach) + { + #include "multi-switch.c" + } + }