[Qemu-devel] [PATCH] target-i386: fix translation of sse {, u}comis{s, d} instructions
While the generic SSE translation codepath contains special logic to use 32-bit or 64-bit memory operands for some instructions, this logic doesn't catch the SSE {,u}comis{s,d} instructions. This oversight leads to too many bytes being read when those instructions use memory operands, which can in turn lead to page faults. The fix is simple: add a special case for these instructions. It did not fit cleanly into the existing case, so some cut-and-paste was necesary. Signed-off-by: Nathan Froyd froy...@mozilla.com --- target-i386/translate.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/target-i386/translate.c b/target-i386/translate.c index be74ebc..687859a 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -4576,6 +4576,16 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, /* 64 bit access */ gen_ldq_env_A0(s-mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0))); } +} else if (b1 = 1 (b == 0x2e || b == 0x2f)) { +/* specific case for SSE *comis{s,d} instructions */ +if (b1 == 0) { +/* 32 bit access */ +gen_op_ld_T0_A0(OT_LONG + s-mem_index); +tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0))); +} else { +/* 64 bit access */ +gen_ldq_env_A0(s-mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0))); +} } else { gen_ldo_env_A0(s-mem_index, op2_offset); } -- 1.7.10.4
Re: [Qemu-devel] Can anybody help me figure out what has been done about floating point multiply in QEMU?
On 05/23/2011 01:36 PM, Guan, Qiang wrote: I want to figure out what is happening in emulating the floating point calculation in QEMU. I checked the codes in target-i386/translate.c, but I cannot find anything about floating point calculation, I can only find the emulation about integer mul or div. My question is what did QEMU do when they need to emulate a floating point calculation? where are these codes? All the code for manipulating floating-point numbers is in the fpu directory. The target-i386 code that calls into those functions is in op_helper.c. HTH, -Nathan
Re: [Qemu-devel] [PATCH v2 1/3] target-ppc: simplify NaN propagation for vector functions
On Wed, Apr 20, 2011 at 01:04:48PM +0100, Peter Maydell wrote: I need to add ARM support for fused multiply-accumulate (vfma,vfms), so perhaps in the long run it would be better to make them softfloat primitives? (they are after all in the new IEEE spec, so they're in softfloat's domain in some sense.) That would move the 'propagate one of 3 NaNs' logic into softfloat. +1 to implementing fma in softfloat. -Nathan
Re: [Qemu-devel] [PATCH 17/19] target-ppc: fix SPE comparison functions
On Tue, Apr 12, 2011 at 11:59:29PM +0200, Aurelien Jarno wrote: Given that float32_*() functions are IEEE754 compliant, the efscmp*() functions are correctly implemented, while efstst*() are not. This patch reverse the implementation of this two groups of functions and fix the comments. It also use float32_eq() instead of float32_eq_quiet() as qNaNs should not be ignored. Thanks for addressing this; the E500 emulation in QEMU is more like how we wish the hardware acted, rather than how it actually acts. :) It's late here, but I think this change: -static inline uint32_t efscmplt(uint32_t op1, uint32_t op2) +static inline uint32_t efststlt(uint32_t op1, uint32_t op2) { -/* XXX: TODO: test special values (NaN, infinites, ...) */ +/* XXX: TODO: ignore special values (NaN, infinites, ...) */ return efststlt(op1, op2); } is not correct, as you've just turned this into an infinite (inlined!) loop. You'd want to change the efststlt call into an efscmplt call. Similarly for efstst{gt,eq}. -Nathan
[Qemu-devel] Re: [PATCH] target-sh4: get rid of CPU_{Float, Double}U
On Sun, Apr 10, 2011 at 09:13:05PM +0200, Aurelien Jarno wrote: SH4 is always using softfloat, so it's possible to have helpers directly taking float32 or float64 value. This allow to get rid of conversions through CPU_{Float,Double}U. Eh, I think this punning on i32/f32 and i64/f64 values is not healthy. But Peter's already said that the floats-as-structs bit of softfloat is broken, so maybe it's not worth trying to ensure floats-as-structs works (or even making it the default, to discourage people from bit-twiddling directly). -Nathan
Re: [Qemu-devel] MIPS64 user mode emulation Patch
On Sat, Mar 26, 2011 at 11:58:37AM +0500, Khansa Butt wrote: Subject: [PATCH] MIPS64 user mode emulation in QEMU This patch adds support for Cavium Network's Octeon 57XX user mode instructions. Octeon 57xx is based on MIPS64. So this patch is the first MIPS64 User Mode Emulation in QEMU This is the team(Khansa Butt, Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed) work of HPCNL Lab at KICS-UET Lahore. Thanks for doing this. As already noted, this patch should be split into at least two patches: one to add Octeon-specific instructions in target-mips/ and one adding the necessary linux-user bits. +extern int TARGET_OCTEON; I don't think a global like this is the right way to go. Perhaps the elfload.c code should set a flag in image_info , which can then be used to set a flag in CPUMIPSState later on. If we must use a global variable, it should be declared in target-mips/cpu.h. @@ -2013,7 +2024,8 @@ void cpu_loop(CPUMIPSState *env) env-active_tc.gpr[5], env-active_tc.gpr[6], env-active_tc.gpr[7], - arg5, arg6/*, arg7, arg8*/); + env-active_tc.gpr[8], + env-active_tc.gpr[9]/*, arg7, arg8*/); } if (ret == -TARGET_QEMU_ESIGRETURN) { /* Returning from a successful sigreturn syscall. This change breaks O32 binaries; it needs to be done in a different way. diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 499c4d7..47fef05 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7195,6 +7195,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_set_thread_area: #if defined(TARGET_MIPS) ((CPUMIPSState *) cpu_env)-tls_value = arg1; + /*tls entry is moved to k0 so that this can be used later*/ + ((CPUMIPSState *) cpu_env)-active_tc.gpr[26] = arg1; ret = 0; break; #elif defined(TARGET_CRIS) I believe this is only correct for Octeon binaries; it's not how the rest of the MIPS world works. It therefore needs to be conditional on Octeon-ness. --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -140,6 +140,20 @@ typedef struct mips_def_t mips_def_t; #define MIPS_FPU_MAX 1 #define MIPS_DSP_ACC 4 +typedef struct cavium_mul cavium_mul; +struct cavium_mul { + target_ulong MPL0; + target_ulong MPL1; + target_ulong MPL2; + target_ulong P0; + target_ulong P1; + target_ulong P2; +}; +typedef struct cvmctl_register cvmctl_register; +struct cvmctl_register { + target_ulong cvmctl; +}; The indentation here needs to be fixed. I don't think there's any reason why these need to be defined outside TCState, either. diff --git a/target-mips/translate.c b/target-mips/translate.c index cce77be..9c3d772 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -36,6 +36,15 @@ #define GEN_HELPER 1 #include helper.h +int TARGET_OCTEON; +#if defined(TARGET_MIPS64) +/*Macros for setting values of cvmctl registers*/ +#define FUSE_START_BIT(cvmctl)(cvmctl | 0x8000) +#define KASUMI(cvmctl)(cvmctl | 0x2000) +#define IPPCI(cvmctl)(cvmctl | 0x380) +#define IPTI(cvmctl)(cvmctl | 0x70) +#endif Please follow existing style; spaces between the comment and comment markers (many examples in translate.c, not just here) and spaces between the macro argument list and definition. @@ -779,7 +818,9 @@ static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv See the MIPS64 PRA manual, section 4.10. */ if (((ctx-hflags MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) !(ctx-hflags MIPS_HFLAG_UX)) { -tcg_gen_ext32s_i64(ret, ret); +/*This function sign extend 32 bit value to 64 bit, was causing error + when ld instruction came.Thats why it is commmented out*/ + /* tcg_gen_ext32s_i64(ret, ret);*/ } #endif } Um, no. If you needed to comment this out, you have a bug someplace else. Don't paper over the bug here. +case OPC_VMULU: +case OPC_V3MULU: These two are large enough that they should be done as out-of-line helpers. Also, since all these new instructions are Octeon-specific, there should be checks emitted to ensure that they produce appropriate errors when non-Octeon hardware is being simulated, similar in style to check_mips_64. /* Arithmetic */ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { const char *opn = arith; +target_ulong mask = 0xFF; I don't think it's really necessary to have this, but if you feel it's necessary, please move the declaration closer to the point of use. +#if defined(TARGET_MIPS64) +static void gen_seqsne (DisasContext *ctx, uint32_t opc, +int rd, int rs, int rt) +{ +const char
Re: [Qemu-devel] [PATCH 1/7] target-arm: Make Neon helper routines use correct FP status
On Mon, Mar 28, 2011 at 03:15:08PM +0100, Peter Maydell wrote: On 14 March 2011 05:35, Nathan Froyd froy...@codesourcery.com wrote: Oh, right. I am ambivalent as to whether passing env to such functions is the right thing to do or not. So did this amount to a request for a change to this patchset, or are you happy to let it pass? I am happy to let it pass. -Nathan
Re: [Qemu-devel] [PATCH 10/17] s390x: Adjust GDB stub
On Thu, Mar 24, 2011 at 04:58:46PM +0100, Alexander Graf wrote: We have successfully lazilized cc computation, so we need to manually trigger its calculation when gdb wants to fetch it. We also changed the variable name, so writing it writes into a different field now. Wouldn't you want to: a) change the variable name in the earlier commit and just do the manual triggering in this commit, so as not to break bisect; or b) combine this change with the previous lazification? -Nathan
Re: [Qemu-devel] [PATCH] target-arm/helper.c: For float-int conversion helpers pass ints as ints
On Mon, Mar 14, 2011 at 05:23:11PM +, Peter Maydell wrote: Correct the argument and return types for the float-int conversion helper functions so that integer arguments and return values are declared as uint32_t/uint64_t, not float32/float64. This allows us to remove the hand-rolled functions which were doing bitwise copies between the types via unions. Reviewed-by: Nathan Froyd froy...@codesourcery.com I like the direction this patch goes; you aren't by any chance going to convert the passing/returning of float* to their appropriate int* types too, are you? -Nathan
Re: [Qemu-devel] [PATCH] target-arm/helper.c: For float-int conversion helpers pass ints as ints
On Mon, Mar 21, 2011 at 02:04:31PM +, Peter Maydell wrote: On 21 March 2011 13:48, Nathan Froyd froy...@codesourcery.com wrote: I like the direction this patch goes; you aren't by any chance going to convert the passing/returning of float* to their appropriate int* types too, are you? Nope -- I think that where we're passing or returning an actual IEEE single/double to a helper function float* is a better type than uint32_t: it gives information about what the helper's argument semantically is, and it means we don't have every helper that takes or returns a float have to include ugly calls to the boxing/unboxing macros. I'm just concerned about what would happen if we turned on softfloat's float types are structure types bit; I'm pretty sure everything would break horribly on targets that don't pass small structures in registers. Admittedly, several targets would be broken by doing so, so it's not particularly urgent. -Nathan
Re: [Qemu-devel] [PATCH] [PPC] Add support for 6 SPE instructions (evmra, evmwsmi{a{a}}, evmwumi{a{a}})
On Wed, Mar 16, 2011 at 11:21:22AM +0100, Fabien Chouteau wrote: Signed-off-by: Fabien Chouteau chout...@adacore.com Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 1/7] target-arm: Make Neon helper routines use correct FP status
On Fri, Mar 11, 2011 at 10:31:31PM +, Peter Maydell wrote: On 11 March 2011 18:30, Nathan Froyd froy...@codesourcery.com wrote: Is there a reason that you don't simply use the global env rather than passing in an extra parameter everywhere? Just following the pattern that generally seems to be used by most helper functions, ie if you want the CPU env pass it in as a parameter. As far as I know, you can't use the global env unless you're in op_helper.c because that's the only source file compiled with the right flags. Oh, right. I am ambivalent as to whether passing env to such functions is the right thing to do or not. I wonder if it'd be worthwhile just to merge these functions into op_helper.c, since we have a proper FP status for NEON bits now. Why move these and not (for instance) the VFP helpers in helper.c which use the CPU env for more or less the same reasons? No reason, other than that I wasn't thinking about the VFP helpers. :) -Nathan
Re: [Qemu-devel] [PATCH 6/7] softfloat: Add float*_min() and float*_max() functions
On Fri, Mar 11, 2011 at 06:12:25PM +, Peter Maydell wrote: Add min and max operations to softfloat. This allows us to implement propagation of NaNs and handling of negative zero correctly (unlike the approach of having target helper routines return one of the operands based on the result of a comparison op). Are these useful anyplace beside ARM? i.e. do they implement the correct AltiVec/VSX/SSE* (any others?) semantics? -Nathan
Re: [Qemu-devel] [PATCH 2/7] target-arm/neon_helper.c: Use make_float32/float32_val macros
On Fri, Mar 11, 2011 at 06:12:21PM +, Peter Maydell wrote: Use the softfloat make_float32 and float32_val macros to convert between softfloat's float32 type and raw uint32_t types, rather than private conversion functions. Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 1/7] target-arm: Make Neon helper routines use correct FP status
On Fri, Mar 11, 2011 at 06:12:20PM +, Peter Maydell wrote: Make the Neon helper routines use the correct FP status from the CPUEnv rather than using a dummy static one. This means they will correctly handle denormals and NaNs and will set FPSCR exception bits properly. Is there a reason that you don't simply use the global env rather than passing in an extra parameter everywhere? I wonder if it'd be worthwhile just to merge these functions into op_helper.c, since we have a proper FP status for NEON bits now. -Nathan
Re: [Qemu-devel] [PATCH] linux-user: bigger default stack
On Thu, Mar 03, 2011 at 05:37:37PM +0200, Riku Voipio wrote: PTHREAD_STACK_MIN (16KB) is somewhat inadequate for a new stack. follow the pthread_create defaults, ie setting to RLIMIT_STACK or if unlimited to 2MB. For what sort oof cases is it inadequate? This stack is just for QEMU's usage and QEMU shouldn't be using very much. The target thread could use quite a bit of course, but that's handled elsewhere. -Nathan
Re: [Qemu-devel] [PATCH] linux-user: bigger default stack
On Thu, Mar 03, 2011 at 06:15:49PM +0200, Riku Voipio wrote: On Thu, Mar 03, 2011 at 07:46:27AM -0800, Nathan Froyd wrote: On Thu, Mar 03, 2011 at 05:37:37PM +0200, Riku Voipio wrote: PTHREAD_STACK_MIN (16KB) is somewhat inadequate for a new stack. follow the pthread_create defaults, ie setting to RLIMIT_STACK or if unlimited to 2MB. For what sort oof cases is it inadequate? This stack is just for QEMU's usage and QEMU shouldn't be using very much. QEMU linux-user calls glibc functions which, while usually very conservative with memory usage, are not guaranteed not take less than 10KB (at do_syscall we are already around 5 functions deep). Bleh. OK, so it needs to be increased. Could we get by with somewhat less (256K?), to try and maximize the number of threads we can potentially run? Maybe it doesn't matter (people creating thousands of simultaneous threads inside QEMU have other problems...), but not gratuitously wasting memory would be good. -Nathan
Re: [Qemu-devel] [PATCH 1/2] target-arm: Move Neon VUZP to a helper function
On Fri, Feb 11, 2011 at 05:12:32PM +, Peter Maydell wrote: On 11 February 2011 17:03, Nathan Froyd froy...@codesourcery.com wrote: I do think the preferred way would be to extract rd, rm, size, and Q up-front, rather than having the helper twiddle instruction bits. OK. You're happy to still have the helper do the reading and writing of env-vfp.regs[] directly, though? I think you can make a case either way, but you're passing enough values already that accessing env-vfp.regs directly in the helper seems reasonable. -Nathan
Re: [Qemu-devel] [PATCH 1/2] target-arm: Move Neon VUZP to a helper function
On Fri, Feb 11, 2011 at 04:53:30PM +, Peter Maydell wrote: On 11 February 2011 16:14, Peter Maydell peter.mayd...@linaro.org wrote: +void HELPER(neon_unzip)(CPUState *env, uint32_t insn) +{ + int rd = ((insn 18) 0x10) | ((insn 12) 0x0f); + int rm = ((insn 1) 0x10) | (insn 0x0f); + int size = (insn 18) 3; + if (insn 0x40) { /* Q */ + uint64_t zm0 = float64_val(env-vfp.regs[rm]); + uint64_t zm1 = float64_val(env-vfp.regs[rm + 1]); + uint64_t zd0 = float64_val(env-vfp.regs[rd]); + uint64_t zd1 = float64_val(env-vfp.regs[rd + 1]); I can rework these patches if people don't like the way this is effectively doing decoding in a helper function, incidentally, although I'm not convinced it would end up any nicer overall. I do think the preferred way would be to extract rd, rm, size, and Q up-front, rather than having the helper twiddle instruction bits. -Nathan
[Qemu-devel] Re: [PATCH 2/2] target-ppc: fix wrong NaN tests
On Wed, Jan 12, 2011 at 07:42:48PM +0100, Aurelien Jarno wrote: Some tests in FPU emulation code were wrongly using float64_is_nan() before commit 185698715dfb18c82ad2a5dbc169908602d43e81, and wrongly using float64_is_quiet_nan() after. Fix them by using float64_is_any_nan() instead. Cc: Alexander Graf ag...@suse.de Cc: Peter Maydell peter.mayd...@linaro.org Cc: Nathan Froyd froy...@codesourcery.com Signed-off-by: Aurelien Jarno aurel...@aurel32.net Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
[Qemu-devel] Re: [PATCH v2 1/2] target-ppc: fix sNaN propagation
On Wed, Jan 12, 2011 at 07:42:47PM +0100, Aurelien Jarno wrote: The current FPU code returns 0.0 if one of the operand is a signaling NaN and the VXSNAN exception is disabled. fload_invalid_op_excp() doesn't return a qNaN in case of a VXSNAN exception as the operand should be propagated instead of a new qNaN to be generated. Fix that by calling fload_invalid_op_excp() only for the exception generation (if enabled), and use the softfloat code to correctly compute the result. Cc: Alexander Graf ag...@suse.de Cc: Peter Maydell peter.mayd...@linaro.org Cc: Nathan Froyd froy...@codesourcery.com Signed-off-by: Aurelien Jarno aurel...@aurel32.net Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 1/9] target-sh4: switch sh4 to softfloat
On Tue, Jan 11, 2011 at 10:01:30PM +0100, Aurelien Jarno wrote: case $target_arch2 in - alpha|arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|s390x|sparc|sparc64|sparc32plus) + alpha|arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|s390x|sh4|sh4eb|sparc|sparc64|sparc32plus) echo CONFIG_SOFTFLOAT=y $config_target_mak ;; *) This is obvious, I think...but it's also a little ridiculous. Why not make everything use softfloat and dispense with this? How much work would it be on the x86 side? -Nathan
Re: [Qemu-devel] [PATCH 1/6] softfloat: remove HPPA specific code
On Thu, Jan 06, 2011 at 03:34:38PM +, Peter Maydell wrote: Similarly I'm dubious about uses in helper_fsel, helper_fcmpu and helper_fcmpo, efsctsi, efsctui, efsctsiz, efsctuiz, efsctsf, efsctuf and all the helper_efd* functions. I haven't actually checked them all, but for instance efdctsi in the Power ISA 2.03 spec says NaNs are converted as though they were zero, but qemu's code says: /* NaN are not treated the same way IEEE 754 does */ if (unlikely(float64_is_quiet_nan(u.d))) return 0; which is not going to do the right thing for signaling NaNs. I think you are correct about fsel, fcmpu, and fcmpo. The E500 FP instructions are broken for various corner cases (and there are a lot of them, because E500 is screwy). I've been meaning to go through and fix them up, but haven't taken the time to do so. -Nathan
Re: [Qemu-devel] [PATCH 6/6] target-ppc: Implement correct NaN propagation rules
On Mon, Jan 03, 2011 at 03:34:33PM +0100, Aurelien Jarno wrote: Implement the correct NaN propagation rules for ARM targets by providing an appropriate pickNaN function. Also fix the #ifdef tests for default NaN definition, the correct name is TARGET_PPC instead of TARGET_POWERPC. Reviewed-by: Nathan Froyd froy...@codesourcery.com + * A signaling NaN is always quietened before returning it. I think silenced is more natural here, but I can understand preferring quiet in keeping with NaN terminology. -Nathan
Re: [Qemu-devel] [PATCH] target-ppc: use float32_is_any_nan()
On Sun, Jan 02, 2011 at 01:06:49PM +0100, Aurelien Jarno wrote: Use the new function float32_is_any_nan() instead of float32_is_quiet_nan() || float32_is_signaling_nan(). Cc: Alexander Graf ag...@suse.de Signed-off-by: Aurelien Jarno aurel...@aurel32.net Reviewed-by: Nathan Froyd froy...@codesourcery.com @@ -1938,7 +1938,7 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ /* If X is a NaN, store the corresponding QNaN into RESULT. Otherwise, * execute the following block. */ #define DO_HANDLE_NAN(result, x)\ -if (float32_is_quiet_nan(x) || float32_is_signaling_nan(x)) { \ +if (float32_is_any_nan(x)) {\ CPU_FloatU __f; \ __f.f = x; \ __f.l = __f.l | (1 22); /* Set QNaN bit. */ \ If you were looking for other cleanups, this could stand a maybe_silence_nan. -Nathan
Re: [Qemu-devel] NPTL support
On Mon, Dec 20, 2010 at 10:17:50PM -0800, maheen butt wrote: hi I 'm working with fedora core 13(64 bit) x86_64 platform. I configured QEMU with --enable-nptl switch but I'm not able to run programs containing POSIX threads or fork system call. I run this commandqemu-x86_64 thread it gives system call errorand qemu-x86_64 forkfno child process createdwhat is reason behind it? is nptl support is in its progressive mode or it is not for x86_64. Nobody's written the x86/x86_64-specific NPTL bits yet. -Nathan
Re: [Qemu-devel] [PATCH V2] softfloat: Rename float*_is_nan() functions to float*_is_quiet_nan()
On Sat, Dec 18, 2010 at 10:39:05AM +, Peter Maydell wrote: On 18 December 2010 02:30, Nathan Froyd froy...@codesourcery.com wrote: So adding _t suffixes in appropriate places should be a no-op, except for uint16/int16--and those types are never used. Eh? If you comment out the int16 typedef you'll find softfloat.c doesn't compile because of all the places it's used... (uint16 isn't used, though.) Sorry about that, I fail at grepping late at night. =/ -Nathan
Re: [Qemu-devel] [PATCH V2] softfloat: Rename float*_is_nan() functions to float*_is_quiet_nan()
On Fri, Dec 17, 2010 at 11:32:03PM +, Peter Maydell wrote: On 17 December 2010 17:54, Andreas Färber andreas.faer...@web.de wrote: My patch does not touch the bits* types. I didn't notice any problem there. I replaced int32 by int32_t, int64 by int64_t etc. No sane code puts more than 32 bits into an int32 variable, and my guests on OSX/ppc64 host still appeared to work. I don't have arm guests though so please check on your side. Hrm. That introduces potential semantic changes, so I'm a bit wary of it (and my test suite is not currently comprehensive enough to be sure of covering all of softfloat)... I'd be happier if we just renamed the int32 friends to some other non-clashing name, if all we're trying to solve is a name clash issue. I wouldn't be too worried: typedef uint8_t flag; typedef uint8_t uint8; typedef int8_t int8; typedef int uint16; typedef int int16; typedef unsigned int uint32; typedef signed int int32; typedef uint64_t uint64; typedef int64_t int64; So adding _t suffixes in appropriate places should be a no-op, except for uint16/int16--and those types are never used. -Nathan
[Qemu-devel] Re: arm: fix ldrexd/strexd
On Thu, Nov 04, 2010 at 07:47:45AM -, Peter Maydell wrote: Correct ldrexd and strexd code to always read and write the high word of the 64-bit value from addr+4. Also make ldrexd and strexd agree that for a 64 bit value the address in env-exclusive_addr is that of the low word. This fixes the issues reported in https://bugs.launchpad.net/qemu/+bug/670883 Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 1/8] ARM: Fix decoding of VFP forms of VCVT between float and int/fixed
On Thu, Nov 11, 2010 at 06:23:55PM +, Peter Maydell wrote: Correct the decoding of source and destination registers for the VFP forms of the VCVT instructions which convert between floating point and integer or fixed-point. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com I don't know how good QEMU's framework is, but it'd be nice to have your testing code checked into the tree, in case anybody decides to do major surgery on the ARM backend. -Nathan
Re: [Qemu-devel] [PATCH 1/8] ARM: Fix decoding of VFP forms of VCVT between float and int/fixed
On Mon, Dec 06, 2010 at 04:48:25PM +, Peter Maydell wrote: I'm not sure how well it would fit into being committed to qemu (yet): it works as a program where you run half of it on real ARM hardware and the other half under qemu (or valgrind) and it compares register results after executing instructions by looking at the sigcontext struct in a signal handler. Plus there's a perl script to generate random instruction set sequences to feed the test program. It could be made more automated and independent of having a reference bit of hardware but I haven't got round to that yet. (Also since it has utility outside of just testing qemu I'm not sure if it really belongs in the qemu repo.) That does sound a little heavyweight. Scripting gdb is also a possibility. FWIW--and this is not particularly conducive to random insn sequences--the approach taken when doing the AltiVec bits was to have code that looked like: for each insn: for a suitable set of inputs: setup interesting registers (status control registers etc.) load inputs into registers execute record interesting post conditions in file.out You'd get an output file from real hardware and an output file from the simulator and then compare them, fixing differences as you go. The actual code included bits to compare the files as well as doing the generation. The output files can be somewhat large, but I'm sure clever engineering could be applied to make them smaller. Of course, the *real* problems are in undefined-behavior land. :) -Nathan
Re: [Qemu-devel] [PATCH 04/10] softfloat: Add float*_is_any_nan() functions
On Mon, Dec 06, 2010 at 05:00:05PM +, Peter Maydell wrote: Add float*_is_any_nan() functions which return true if the argument is a NaN of any kind (quiet or signalling). Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 06/10] softfloat: Add float*_maybe_silence_nan() functions
On Mon, Dec 06, 2010 at 05:00:07PM +, Peter Maydell wrote: Add functions float*_maybe_silence_nan() which ensure that a value is not a signaling NaN by turning it into a quiet NaN. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 07/10] ARM: Return correct result for single-double conversion of NaN
On Mon, Dec 06, 2010 at 05:00:08PM +, Peter Maydell wrote: The ARM ARM defines that if the input to a single-double conversion is a NaN then the output is always forced to be a quiet NaN by setting the most significant bit of the fraction part. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 05/10] ARM: Return correct result for float-to-integer conversion of NaN
On Mon, Dec 06, 2010 at 05:00:06PM +, Peter Maydell wrote: The ARM architecture mandates that converting a NaN value to integer gives zero (if Invalid Operation FP exceptions are not being trapped). This isn't the behaviour of the SoftFloat library, so NaNs must be special-cased. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 08/12] ARM: Return correct result for single-double conversion of NaN
On Tue, Nov 30, 2010 at 11:15:56AM +, Peter Maydell wrote: On 29 November 2010 19:54, Nathan Froyd froy...@codesourcery.com wrote: Yes, this is ugly. Are you up for running: perl -p -i -e 's/float(\d+)_is_nan/float\1_is_quiet_nan/g' target-*/*.c (and also carefully in fpu/*) or similar and moving the bit-twiddling float_is_nan into fpu/? I'm just compiling this up now. While I was eyeballing the results of the substitution, I noticed that there are some places which are almost certainly bugs introduced by other people not noticing that float*_is_nan() doesn't do what it says on the tin. Three at random: In target-ppc/op_helper.c:helper_compute_fprf(): In target-alpha/op_helper.c:helper_cmptun(): In target-m68k/helper.c:sub_cmp_f64: judging from the comments the author expected is_nan() to be true for all NaNs. I'm not sure what we should do about these -- they look wrong but I don't have any of the setup to actually test whether they're wrong. RTH (CC'd) is the expert on the Alpha bits. The PPC one is obviously wrong. I can test the m68k one. In any event, I think the safest course is to do the simple renaming; we can clean up broken bits after the fact. -Nathan
Re: [Qemu-devel] [PATCH 08/12] ARM: Return correct result for single-double conversion of NaN
On Wed, Dec 01, 2010 at 09:52:13AM -0800, Richard Henderson wrote: I think I've lost the thread a bit -- is the proposal to replace the existing float*_is_nan with _is_quiet_nan and invent a new function that returns true for both Q+S? That at least would be monotonic improvement for Alpha, although as noted above not 100% correct. Yes, that's the plan. As (planned to be) implemented, doing this should not change anything: 1. s/float*_is_nan/float*_is_quiet_nan/g 2. write new float*_is_nan 3. use new float*_is_nan in new code 4. replace bogus float*_is_quiet_nan uses with new function -Nathan
[Qemu-devel] Re: [PATCH] softfloat: Rename float*_is_nan() functions to float*_is_quiet_nan()
On Tue, Nov 30, 2010 at 11:25:33AM +, Peter Maydell wrote: The softfloat functions float*_is_nan() were badly misnamed, because they return true only for quiet NaNs, not for all NaNs. Rename them to float*_is_quiet_nan() to more accurately reflect what they do. This change was produced by: perl -p -i -e 's/_is_nan/_is_quiet_nan/g' $(git grep -l is_nan) (with the results manually checked.) Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com Thank you for doing this. -Nathan
Re: Windows host support [was: Re: [Qemu-devel] CFP: 1st International QEMU Users Forum]
On Mon, Nov 29, 2010 at 08:34:28AM -0600, Anthony Liguori wrote: On 11/28/2010 04:56 AM, Alexander Graf wrote: On 28.11.2010, at 01:17, Nathan Froyd wrote: We (CodeSourcery) are very interested in Windows host support. (We distribute QEMU with our commerical development products for ARM/PowerPC/MIPS/SH/ColdFire/x86.) Unfortunately, we've mostly been backporting patches lately and haven't done a full merge from upstream in some time, so we haven't noticed any potential breakage. If somebody wanted to point out to me what the (potential) Windows issues are, we could take a look. Redirecting you to Anthony here for the specifics. The main problem is that we don't have anyone who takes the lead on Windows support. _If_ something breaks of _if_ we need someone to take over the windows specific parts, there's this huge gap. Uh, Windows system simulation has never worked reliably. It doesn't even have proper AIO support. If someone is building a product based on it, I'm amazed. Well, technically we only support QEMU as a simple instruction set simulator in our products, and the bits present work well enough for that. (It is of course possible those bits have been broken in the time since our last upstream merge.) If you want to venture into system simulation and it breaks, then you get to keep both pieces. It would, however, be better to eventually support full system simulation, and making Windows hosts work right would be a necessary precondition to that. -Nathan
Re: [Qemu-devel] CFP: 1st International QEMU Users Forum
On Mon, Nov 29, 2010 at 02:58:57PM +0100, Alexander Graf wrote: Nathan Froyd a écrit : I'm sorry, what are the both talks you refer to above? Are you proposing an additional talk alongside your (Frédéric's) existing talk? No! I am very happy that you take over the introduction of the emulation. Indeed I was thinking that Alexander could be willing to introduce i.e. device emulation (he'll tell us). Can you send a title of yours ? Or shall we keep the same one, as it will be along these lines ? I'm not sure I fully understand :). Peter is your man when it comes to ARM. I can give a general overview on qemu and know my way around most subsystems, but I'm not exactly strong in ARM :). I am confused too. Is Alexander giving the talk, or am I, or some combination of Alexander/Peter/me? Or were you (Frédéric) thinking that Alexander should give a second, separate talk? Nathan and Peter, are you two going anyways, despite giving a talk or not? I'm certainly going to try, yes. -Nathan
Re: [Qemu-devel] [PATCH 06/12] ARM: Fix sense of to_integer bit in Neon VCVT float/int conversion
On Tue, Nov 23, 2010 at 06:53:45PM +, Peter Maydell wrote: Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 07/12] ARM: Return correct result for float-to-integer conversion of NaN
On Tue, Nov 23, 2010 at 06:53:46PM +, Peter Maydell wrote: The ARM architecture mandates that converting a NaN value to integer gives zero (if Invalid Operation FP exceptions are not being trapped). This isn't the behaviour of the SoftFloat library, so NaNs must be special-cased. +/* Helper routines to identify NaNs. Note that softfloat's + * floatxx_is_nan() actually only returns true for quiet NaNs. + * A NaN has an exponent field all 1s and a fraction field + * anything except all zeros. Conveniently we can detect this + * by masking out the sign bit and doing an unsigned comparison. + */ +static int float32_is_any_nan(float32 x) +{ +return ((float32_val(x) ~(1 31)) 0x7f80UL); +} + +static int float64_is_any_nan(float64 x) +{ +return ((float64_val(x) ~(1ULL 63)) 0x7ff0ULL); +} Why not just use: static int float32_is_any_nan(float32 x) { return float32_is_nan(x) || float32_is_signaling_nan(x); } and likewise for the 64-bit case? -Nathan
Re: [Qemu-devel] [PATCH 07/12] ARM: Return correct result for float-to-integer conversion of NaN
On Mon, Nov 29, 2010 at 04:49:24PM +, Peter Maydell wrote: On 29 November 2010 16:38, Nathan Froyd froy...@codesourcery.com wrote: Why not just use: static int float32_is_any_nan(float32 x) { return float32_is_nan(x) || float32_is_signaling_nan(x); } and likewise for the 64-bit case? That was what my first-pass patches did, but I rewrote them this way because it seemed more straightforward to just test for is this a NaN rather than calling two other functions which each test for is this some subset of NaN space. I suppose you could argue that softfloat ought to have _is_nan() [with the semantics you'd expect from the function name, not the ones it currently has!], _is_signalling_nan() and _is_quiet_nan() functions built in, but it doesn't... I agree that the functions are poorly named. I think it'd be better to leave the bit-twiddling to the softfloat bits, though. There's precedent for the more verbose approach in other backends, too. -Nathan
Re: [Qemu-devel] [PATCH 02/12] target-arm: Fix mixup in decoding of saturating add and sub
On Tue, Nov 23, 2010 at 06:53:41PM +, Peter Maydell wrote: From: Johan Bengtsson teofrast...@gmail.com The thumb2 decoder contained a mixup between the bit controlling doubling and the bit controlling if the operation was an add or a sub. Signed-off-by: Johan Bengtsson teofrast...@gmail.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 09/12] ARM: Ignore top 16 bits when doing VCVT from 16 bit fixed point
On Tue, Nov 23, 2010 at 06:53:48PM +, Peter Maydell wrote: VCVT of 16 bit fixed point to float should ignore the top 16 bits of the source register. Cast to int16_t and friends rather than int16 -- the former is guaranteed exactly 16 bits wide where the latter is merely at least 16 bits wide (and so is usually 32 bits). Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 08/12] ARM: Return correct result for single-double conversion of NaN
On Tue, Nov 23, 2010 at 06:53:47PM +, Peter Maydell wrote: The ARM ARM defines that if the input to a single-double conversion is a NaN then the output is always forced to be a quiet NaN by setting the most significant bit of the fraction part. Signed-off-by: Peter Maydell peter.mayd...@linaro.org @@ -2529,12 +2529,26 @@ float32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env) /* floating point conversion */ float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env) { -return float32_to_float64(x, env-vfp.fp_status); +float64 r = float32_to_float64(x, env-vfp.fp_status); +/* ARM requires that S-D conversion of any kind of NaN generates + * a quiet NaN by forcing the most significant frac bit to 1. + */ +if (float64_is_signaling_nan(r)) { +return make_float64(float64_val(r) | (1LL 51)); +} +return r; } As with other NaN-handling patches, I don't think the bit-twiddling here is a good idea. Having a float*_maybe_silence_nan function in softfloat would be a better approach. -Nathan
Re: [Qemu-devel] [PATCH 05/12] ARM: Fix decoding of Neon forms of VCVT between float and fixed point
On Tue, Nov 23, 2010 at 06:53:44PM +, Peter Maydell wrote: Fix errors in the decoding of the Neon forms of fixed-point VCVT: * fixed-point VCVT is op 14 and 15, not 15 and 16 * the fbits immediate field was being misinterpreted * the sense of the to_fixed bit was inverted Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 03/12] target-arm: Handle 'smc' as an undefined instruction
On Tue, Nov 23, 2010 at 06:53:42PM +, Peter Maydell wrote: From: Adam Lackorzynski a...@os.inf.tu-dresden.de Refine check on bkpt so that smc and undefined instruction encodings are handled as an undefined instruction and trap. Signed-off-by: Adam Lackorzynski a...@os.inf.tu-dresden.de Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 01/12] target-arm: Add support for PKHxx in thumb2
On Tue, Nov 23, 2010 at 06:53:40PM +, Peter Maydell wrote: From: Johan Bengtsson teofrast...@gmail.com The PKHxx instructions were not recognized by the thumb2 decoder. The solution provided in this changeset is identical to the arm-mode implementation. Signed-off-by: Johan Bengtsson teofrast...@gmail.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 10/12] softfloat: Add float/double to 16 bit integer conversion functions
On Tue, Nov 23, 2010 at 06:53:49PM +, Peter Maydell wrote: The ARM architecture needs float/double to 16 bit integer conversions. (The 32 bit versions aren't sufficient because of the requirement to saturate at 16 bit MAXINT/MININT and to get the exception bits right.) Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 11/12] ARM: Implement VCVT to 16 bit integer using new softfloat routines
On Tue, Nov 23, 2010 at 06:53:50PM +, Peter Maydell wrote: Use the softfloat conversion routines for conversion to 16 bit integers, because just casting to a 16 bit type truncates the value rather than saturating it at 16-bit MAXINT/MININT. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 1/6] ARM: linux-user: Correct size of padding in target_ucontext_v2
On Wed, Nov 24, 2010 at 03:20:03PM +, Peter Maydell wrote: The padding in the target_ucontext_v2 is defined by the size of the target's sigset_t type, not the host's. (This bug only causes problems when we start using the uc_regspace[] array to expose VFP registers to userspace signal handlers.) Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 2/6] ARM: Expose vfp_get_fpscr() and vfp_set_fpscr() to C code
On Wed, Nov 24, 2010 at 03:20:04PM +, Peter Maydell wrote: Expose the vfp_get_fpscr() and vfp_set_fpscr() functions to C code as well as generated code, so we can use them to read and write the FPSCR when saving and restoring VFP registers across signal handlers in linux-user mode. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 3/6] ARM: linux-user: Expose VFP registers to signal handlers
On Wed, Nov 24, 2010 at 03:20:05PM +, Peter Maydell wrote: For ARM linux-user mode signal handlers, fill in the ucontext with VFP register contents in the same way that the kernel does. We only do this for v2 format sigframe (2.6.12 and above); this is actually bug-for-bug compatible with the older kernels, which don't save and restore VFP registers either. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 4/6] ARM: linux-user: Restore VFP state from ucontext on sigreturn
On Wed, Nov 24, 2010 at 03:20:06PM +, Peter Maydell wrote: Restore the VFP registers from the ucontext on return from a signal handler in linux-user mode. This means that signal handlers cannot accidentally corrupt the interrupted code's VFP state, and allows them to deliberately modify the state via the ucontext structure. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 4/6] ARM: linux-user: Restore VFP state from ucontext on sigreturn
On Wed, Nov 24, 2010 at 03:20:06PM +, Peter Maydell wrote: Restore the VFP registers from the ucontext on return from a signal handler in linux-user mode. This means that signal handlers cannot accidentally corrupt the interrupted code's VFP state, and allows them to deliberately modify the state via the ucontext structure. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Nathan Froyd froy...@codesourcery.com -Nathan
Re: [Qemu-devel] [PATCH 08/12] ARM: Return correct result for single-double conversion of NaN
On Mon, Nov 29, 2010 at 07:25:18PM +, Peter Maydell wrote: On 29 November 2010 17:49, Nathan Froyd froy...@codesourcery.com wrote: On Tue, Nov 23, 2010 at 06:53:47PM +, Peter Maydell wrote: As with other NaN-handling patches, I don't think the bit-twiddling here is a good idea. Having a float*_maybe_silence_nan function in softfloat would be a better approach. I guess this (like the other one you commented on) boils down to how you want to approach the boundary between qemu proper and the softfloat library. There are three approaches I can see: (a) live with the softfloat API as it is, and add bit twiddling as necessary for particular target CPU special casing in the per-cpu functions (which is what I was doing here and with the 'is it a NaN?' function in the other patch) Full disclosure: I did this sort of thing for PPC; see the DO_HANDLE_NAN macro in op_helper.c. I was young and thoughtless then and now I am...well, older, anyway. :) I don't think it's the best approach: since at least two CPUs now need NaN-silencing, we should provide something generic. And even if only one CPU requires it, I think it's better to squirrel the logic away in fpu/. float{32,64,80,128} should be opaque things except for specialized cases. (I can see an argument for CPU-confined bit twiddling to implement things like float*_rsqrt_estimate or similar, where one function might not work across CPU families due to precision requirements and so forth. But we can cross that bridge when we come to it.) (b) add to and extend the softfloat API whenever you have some floating-point related thing it doesn't currently support (which I did with the add conversions to int16_t patch because it was a big chunk of bit twiddling, but which I felt was a bit invasive to do for this sort of minor tweak, especially since softfloat is a copy of a third-party library) I think this is the best approach whenever possible. I would not be too worried about the third-party-ness of softfloat; it's extremely stable, unlikely to change anytime in the near or far future, and we've already extended in it non-trivial ways anyway. (And would do so again if we ever implemented, say, proper flush-to-zero denormal handling or IA64 register-precision floats--the former being more likely than the latter. ;) An example of where softfloat could be usefully extended and where we do (a) sometimes is in production of CPU-default NaN values. softfloat knows all about this, yet there are #defines scattered about to provide bit patterns because the softfloat API isn't extensive enough. (c) do something suboptimal where the softfloat API provides some-API-but-not-quite-the-ideal-API (which I'm not particularly keen on and is what I see the is_nan() || is_signalling_nan() approach as) Yes, this is ugly. Are you up for running: perl -p -i -e 's/float(\d+)_is_nan/float\1_is_quiet_nan/g' target-*/*.c (and also carefully in fpu/*) or similar and moving the bit-twiddling float_is_nan into fpu/? -Nathan
Re: [Qemu-devel] [PATCH 08/12] ARM: Return correct result for single-double conversion of NaN
On Mon, Nov 29, 2010 at 08:04:42PM +, Peter Maydell wrote: On 29 November 2010 19:54, Nathan Froyd froy...@codesourcery.com wrote: On Mon, Nov 29, 2010 at 07:25:18PM +, Peter Maydell wrote: (b) add to and extend the softfloat API whenever you have some floating-point related thing it doesn't currently support I think this is the best approach whenever possible. OK. Do we care about maintaining consistency of the API between softfloat and softfloat-native (the latter used only on x86, x86_64, cris, sh4, sh4eb)? softfloat-native should just go away. I would not worry about API compatibility between native and non-native configurations there. (c) do something suboptimal where the softfloat API provides some-API-but-not-quite-the-ideal-API (which I'm not particularly keen on and is what I see the is_nan() || is_signalling_nan() approach as) Yes, this is ugly. Are you up for running: perl -p -i -e 's/float(\d+)_is_nan/float\1_is_quiet_nan/g' target-*/*.c (and also carefully in fpu/*) or similar and moving the bit-twiddling float_is_nan into fpu/? I'm happy to produce a patch doing that if it will be committed :-) Well, I can't promise the committal part... :) -Nathan
Re: [Qemu-devel] CFP: 1st International QEMU Users Forum
On Sun, Nov 28, 2010 at 09:20:25AM +0100, Frédéric Pétrot wrote: IMHO someone from code sourcery would be great, as they (Paul Brooks in the older versions, it seems that Nathan is now taking over) are contributing most of the ARM emulation stuff. Well, Paul still knows way more than I do. I also have not done very much of the ARM stuff; my focus has been on the MIPS and PowerPC side of things. I think Peter has posted more in the way of ARM patches in the last two weeks than we have done for the last year or so. :) (FWIW, I do plan to add Reviewed-by tags to those this week.) We may also have both talks organized one after the other covering both topics, but then Wolfgang and I have to see how to fit into the time and financial envelops (we can only pay the entrance fee for one people). This is now a choice to be made by the qemu-devel people. Please try to converge fast, so that we are in time for the DATE booklet. I'm sorry, what are the both talks you refer to above? Are you proposing an additional talk alongside your (Frédéric's) existing talk? -Nathan
Re: [Qemu-devel] CFP: 1st International QEMU Users Forum
On Sat, Nov 27, 2010 at 11:26:05PM +0100, Alexander Graf wrote: On 27.11.2010, at 20:00, Peter Maydell peter.mayd...@linaro.org wrote: On 26 November 2010 16:34, wolfgang mueller wolfg...@acm.org wrote: In this case is it possible to do the introductionary talk of the workshop with a QEMU overview. People are here interested in QEMU CPU (and evtl. device) emulation. Most of the attending people from industry (!) and universities will have ARM background/interests. Thanks, but really I feel like I'm just getting started with QEMU development myself, so I'm not sure I would be the best person to give a talk like that. I'm sure there's somebody else on the mailing list who would be better suited. My offer stands. If we don't find anyone else, I'll jump in. Generic qemu stuff I can always talk about ;) I would be happy to come and give an overview talk. I don't know that our process for getting in patches that are non-x86+virtualization related are really that good, but perhaps we can have a discussion about that so that we have a better story to tell by March. :) -Nathan
Windows host support [was: Re: [Qemu-devel] CFP: 1st International QEMU Users Forum]
On Fri, Nov 26, 2010 at 01:26:31AM +0100, François Revol wrote: the people we are addressing and we would like to bring together is from the QEMU emulation community. We are interested in running different ISAs mainly under Linux and Windows versions. There is a huge additional You're about the first person in 1/2 year that actually said you care about Windows hosts. Windows support for example is currently on the verge of getting deprecated, because we're lacking a maintainer. I suppose windows users are not as much used/interested/involved into free software development workflows, and probably don't bother even lurking on the developer mailing lists. They only shout when something breaks :p We (CodeSourcery) are very interested in Windows host support. (We distribute QEMU with our commerical development products for ARM/PowerPC/MIPS/SH/ColdFire/x86.) Unfortunately, we've mostly been backporting patches lately and haven't done a full merge from upstream in some time, so we haven't noticed any potential breakage. If somebody wanted to point out to me what the (potential) Windows issues are, we could take a look. -Nathan
Re: [Qemu-devel] [PATCH 4/8] ARM: Return correct result for float-to-integer conversion of NaN
On Thu, Nov 11, 2010 at 06:23:58PM +, Peter Maydell wrote: The ARM architecture mandates that converting a NaN value to integer gives zero. This isn't the behaviour of the SoftFloat library, so NaNs must be special-cased. This is correct, but it's really only correct if FP traps are disabled. (Also, the arm routines returning float* values is just awful. Not your fault, just a comment.) -Nathan
Re: [Qemu-devel] Bug report about x86 'bt' insn
On Sat, Nov 06, 2010 at 07:24:39PM +0100, Torbjorn Granlund wrote: malc av1...@comtv.ru writes: ZF is undefined according to AMD's 24594.pdf page 69. Ah, you're right. It seems that all existing x86 implementations leave ZF alone, though. (I am not arguing that qeum is broken, the bug is in my code.) FWIW, the Intel manuals (253666, June 2010) state that the ZF flag is unaffected, not just undefined. -Nathan
[Qemu-devel] [PATCH] target-mips: fix translation of MT instructions
The translation of dmt/emt/dvpe/evpe was doing the moral equivalent of: int x; ... /* no initialization of x */ x = f (x); which confused later bits of TCG rather badly, leading to crashes. Fix the helpers to only return results (those instructions have no inputs), and fix the translation code accordingly. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/helper.h|8 target-mips/op_helper.c | 28 target-mips/translate.c |8 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/target-mips/helper.h b/target-mips/helper.h index cb13fb2..297ab64 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -154,10 +154,10 @@ DEF_HELPER_2(mttlo, void, tl, i32) DEF_HELPER_2(mtthi, void, tl, i32) DEF_HELPER_2(mttacx, void, tl, i32) DEF_HELPER_1(mttdsp, void, tl) -DEF_HELPER_1(dmt, tl, tl) -DEF_HELPER_1(emt, tl, tl) -DEF_HELPER_1(dvpe, tl, tl) -DEF_HELPER_1(evpe, tl, tl) +DEF_HELPER_0(dmt, tl) +DEF_HELPER_0(emt, tl) +DEF_HELPER_0(dvpe, tl) +DEF_HELPER_0(evpe, tl) #endif /* !CONFIG_USER_ONLY */ /* microMIPS functions */ diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 41abd57..ec6864d 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1554,40 +1554,28 @@ void helper_mttdsp(target_ulong arg1) } /* MIPS MT functions */ -target_ulong helper_dmt(target_ulong arg1) +target_ulong helper_dmt(void) { // TODO -arg1 = 0; -// rt = arg1 - -return arg1; + return 0; } -target_ulong helper_emt(target_ulong arg1) +target_ulong helper_emt(void) { // TODO -arg1 = 0; -// rt = arg1 - -return arg1; +return 0; } -target_ulong helper_dvpe(target_ulong arg1) +target_ulong helper_dvpe(void) { // TODO -arg1 = 0; -// rt = arg1 - -return arg1; +return 0; } -target_ulong helper_evpe(target_ulong arg1) +target_ulong helper_evpe(void) { // TODO -arg1 = 0; -// rt = arg1 - -return arg1; +return 0; } #endif /* !CONFIG_USER_ONLY */ diff --git a/target-mips/translate.c b/target-mips/translate.c index d62c615..c4c44c1 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -12033,22 +12033,22 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch) switch (op2) { case OPC_DMT: check_insn(env, ctx, ASE_MT); -gen_helper_dmt(t0, t0); +gen_helper_dmt(t0); gen_store_gpr(t0, rt); break; case OPC_EMT: check_insn(env, ctx, ASE_MT); -gen_helper_emt(t0, t0); +gen_helper_emt(t0); gen_store_gpr(t0, rt); break; case OPC_DVPE: check_insn(env, ctx, ASE_MT); -gen_helper_dvpe(t0, t0); +gen_helper_dvpe(t0); gen_store_gpr(t0, rt); break; case OPC_EVPE: check_insn(env, ctx, ASE_MT); -gen_helper_evpe(t0, t0); +gen_helper_evpe(t0); gen_store_gpr(t0, rt); break; case OPC_DI: -- 1.6.3.2
[Qemu-devel] [PATCH] linux-user: fix memory leaks with NPTL emulation
Running programs that create large numbers of threads, such as this snippet from libstdc++'s pthread7-rope.cc: const int max_thread_count = 4; const int max_loop_count = 1; ... for (int j = 0; j max_loop_count; j++) { ... for (int i = 0; i max_thread_count; i++) pthread_create (tid[i], NULL, thread_main, 0); for (int i = 0; i max_thread_count; i++) pthread_join (tid[i], NULL); } in user-mode emulation will quickly run out of memory. This is caused by a failure to free memory in do_syscall prior to thread exit: /* TODO: Free CPU state. */ pthread_exit(NULL); The first step in fixing this is to make all TaskStates used by QEMU dynamically allocated. The TaskState used by the initial thread was not, as it was allocated on main's stack. So fix that, free the cpu_env, free the TaskState, and we're home free, right? Not exactly. When we create a thread, we do: ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE); ... new_stack = ts-stack; ... ret = pthread_attr_setstack(attr, new_stack, NEW_STACK_SIZE); If we blindly free the TaskState, then, we yank the current (host) thread's stack out from underneath it while it still has things to do, like calling pthread_exit. That causes problems, as you might expect. The solution adopted here is to let the C library allocate the thread's stack (so the C library can properly clean it up at pthread_exit) and provide a hint that we want NEW_STACK_SIZE bytes of stack. With those two changes, we're done, right? Well, almost. You see, we're creating all these host threads and their parent threads never bother to check that their children are finished. There's no good place for the parent threads to do so. Therefore, we need to create the threads in a detached state so the parent thread doesn't have to call pthread_join on the child to release the child's resources; the child does so automatically. With those three major changes, we can comfortably run programs like the above without exhausting memory. We do need to delete 'stack' from the TaskState structure. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- linux-user/main.c|4 ++-- linux-user/qemu.h|2 -- linux-user/syscall.c | 11 +++ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index dbba8be..7d41d4a 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2711,7 +2711,7 @@ int main(int argc, char **argv, char **envp) struct target_pt_regs regs1, *regs = regs1; struct image_info info1, *info = info1; struct linux_binprm bprm; -TaskState ts1, *ts = ts1; +TaskState *ts; CPUState *env; int optind; const char *r; @@ -3038,7 +3038,7 @@ int main(int argc, char **argv, char **envp) } target_argv[target_argc] = NULL; -memset(ts, 0, sizeof(TaskState)); +ts = qemu_mallocz (sizeof(TaskState)); init_task_state(ts); /* build Task State */ ts-info = info; diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 708021e..00c6549 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -126,8 +126,6 @@ typedef struct TaskState { struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ struct sigqueue *first_free; /* first free siginfo queue entry */ int signal_pending; /* non zero if a signal may be pending */ - -uint8_t stack[0]; } __attribute__((aligned(16))) TaskState; extern char *exec_path; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d44f512..5761106 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3601,9 +3601,8 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, new_thread_info info; pthread_attr_t attr; #endif -ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE); +ts = qemu_mallocz(sizeof(TaskState)); init_task_state(ts); -new_stack = ts-stack; /* we create a new CPU instance. */ new_env = cpu_copy(env); #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC) @@ -3639,7 +3638,8 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, info.parent_tidptr = parent_tidptr; ret = pthread_attr_init(attr); -ret = pthread_attr_setstack(attr, new_stack, NEW_STACK_SIZE); +ret = pthread_attr_setstacksize(attr, NEW_STACK_SIZE); +ret = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED); /* It is not safe to deliver signals until the child has finished initializing, so temporarily block all signals. */ sigfillset(sigmask); @@ -3667,6 +3667,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, if (flags CLONE_NPTL_FLAGS2) return -EINVAL; /* This is probably going to die very quickly, but do it anyway
Re: [Qemu-devel] [PATCH] Refactor flush of per-CPU virtual TB cache
On Tue, Oct 19, 2010 at 09:57:13PM +0200, Lluís wrote: --- a/exec.c +++ b/exec.c @@ -688,6 +688,11 @@ static void page_flush_tb(void) } } +void tb_flush_jmp_cache (CPUState * env) +{ +memset (env-tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *)); +} + This is only used in this file. Why not make it static? -Nathan
Re: [Qemu-devel] Re: [PATCH 10/14] Zero json struct with memset() instea of = {} to keep compiler happy.
On Mon, Aug 30, 2010 at 10:48:55AM -0500, Anthony Liguori wrote: No, this is GCC being stupid. How else do you terminate a list? IOW: MyDeviceInfo device_infos[] = { {foo, 0, 2}, {bar, 0, 1}, {} /* or { 0 } */ }; This is such a pervasive idiom that there's simply no way that GCC can possibly try to warn against this. Plus, it's entirely reasonable. I think this is just a false positive in GCC. Otherwise, there's a ton of code that it should be throwing warnings against. Well, it sounds like Jes was compiling QEMU was extra warning flags, and I doubt people do much beyond -Wall and maybe one or two others. I could see petitioning GCC to only complain if -pedantic. -Nathan
[Qemu-devel] [Bug 617528] Re: Incorrect translation of unary PPC/SPE instructions (efdneg etc.)
Your patch needs a Signed-off-by and preferably a From: as well. ** Tags added: powerpc -- Incorrect translation of unary PPC/SPE instructions (efdneg etc.) https://bugs.launchpad.net/bugs/617528 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: New Bug description: The translation for the following PPC/SPE (e500) instructions is wrong in QEMU git 6cbf4c8c: evfsabs, evfsnabs, evfsneg efdabs, efdnabs, efdneg efsabs, efsnabs, efsneg As you can see from the provided patch, these ought to write their result to the destination register (rD) and not modify the source register (rA) in-place. It's rather hard to generate a test-case for this with GCC, since it likes to put the input and output of a unary operation into the same registers (that's probably also the reason why this went unnoticed). There is however a broken code path in the EGLIBC function for sin() when compiled for e500v2. It returns nonsense results for e.g. -1.0. Trivial test code follows: #include stdio.h #include stdlib.h #include math.h int main(int argc, char **argv) { double x = strtod(argv[1], NULL); printf(%.14g\n, sin(x)); return 0; } Result before the patch (WRONG): $ qemu-ppc -cpu e500v2 sintest -1.0 -1 Result after the patch (OK): $ qemu-ppc -cpu e500v2 sintest -1.0 -0.84147071838379 A self-contained test-case using inline assembler can be provided upon request.
Re: [Qemu-devel] Implementing atomic SWP in qemu-arm
On Wed, Aug 18, 2010 at 12:15:09PM -0700, Peter W Schultz wrote: How would I go about modifying the qemu source to implement SWP atomically? I have been studying the source for a few days now, and I am at a loss as to what all needs to be done. You should look at how the load/store-exclusive instructions work and see if you can use a similar mechanism. It should be fairly straightforward. I feel it would be most desirable to add a TCG_SWAP instruction that is guaranteed to be an atomic compare-and-swap, and implement that as needed. I believe there was an thread several months ago discussing doing this or something similar and it was decided that mechanism was not the way to go. -Nathan
Re: [Qemu-devel] [PATCH 0/2] target-sh4: Add support for missing ldc stc instructions with sgr
On Fri, Jul 09, 2010 at 03:38:34PM +0900, Alexandre Courbot wrote: This series of patch adds support for the missing ldc stc privileged instructions with the sgr register. In order to take the difference of support between SH4A and SH4 (which does not recognize ldc with sgr), the LDST macro has been split into two simpler macros. Both of your patches need a Signed-off-by line (git format-patch -s). -Nathan
Re: [Qemu-devel] [PATCH 0/8] target-mips: add microMIPS ASE support, v3
On Wed, Jun 09, 2010 at 04:10:25PM +0200, Aurelien Jarno wrote: On Tue, Jun 08, 2010 at 01:29:55PM -0700, Nathan Froyd wrote: This patch series adds support for the microMIPS ASE. microMIPS is a new ASE similar to MIPS16, but re-encodes the entire instruction set into 16-bit and 32-bit instructions--in contrast to MIPS16, which re-encodes only integer instructions. The mechanisms for going in and out of microMIPS mode are identical to those for MIPS16; a given chip cannot support both ASEs simultaneously. I have applied all patches except the 5th one, see my comments about it. Thanks for applying these. I agree with you about the 5th one and will submit a M14K patch in the next week. Finally, I have made some comments about the 4th patch, that may be a basis for future improvements. Indeed. I will work on that one. -Nathan
[Qemu-devel] [PATCH 0/8] target-mips: add microMIPS ASE support, v3
This patch series adds support for the microMIPS ASE. microMIPS is a new ASE similar to MIPS16, but re-encodes the entire instruction set into 16-bit and 32-bit instructions--in contrast to MIPS16, which re-encodes only integer instructions. The mechanisms for going in and out of microMIPS mode are identical to those for MIPS16; a given chip cannot support both ASEs simultaneously. changes from v2: give actual name to FOP constants; assign names to FOPs for c{,abs} fix up coding style violations fix helpers for recent ldl_*/stl_* prototype changes split out mips16-related changes into separate patch group patches more logically changes from v1: fix re-introduction of previously deleted code noted by rth Nathan Froyd (8): target-mips: define constants for magic numbers target-mips: refactor c{,abs}.cond.fmt insns target-mips: mips16 cleanups target-mips: microMIPS ASE support target-mips: add microMIPS CPUs target-mips: add microMIPS exception handler support linux-user: honor low bit of entry PC for MIPS hw: honor low bit in mipssim machine hw/mips_mipssim.c|5 +- linux-user/main.c|5 +- target-mips/cpu.h|1 + target-mips/helper.c | 21 +- target-mips/helper.h |9 + target-mips/mips-defs.h |1 + target-mips/op_helper.c | 136 ++ target-mips/translate.c | 3015 ++ target-mips/translate_init.c | 61 + 9 files changed, 3009 insertions(+), 245 deletions(-)
[Qemu-devel] [PATCH 7/8] linux-user: honor low bit of entry PC for MIPS
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- linux-user/main.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 0f23fc9..ad292f1 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3271,7 +3271,10 @@ int main(int argc, char **argv, char **envp) for(i = 0; i 32; i++) { env-active_tc.gpr[i] = regs-regs[i]; } -env-active_tc.PC = regs-cp0_epc; +env-active_tc.PC = regs-cp0_epc ~(target_ulong)1; +if (regs-cp0_epc 1) { +env-hflags |= MIPS_HFLAG_M16; +} } #elif defined(TARGET_SH4) { -- 1.6.3.2
[Qemu-devel] [PATCH 8/8] hw: honor low bit in mipssim machine
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- hw/mips_mipssim.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c index a747de5..293d99e 100644 --- a/hw/mips_mipssim.c +++ b/hw/mips_mipssim.c @@ -106,7 +106,10 @@ static void main_cpu_reset(void *opaque) CPUState *env = s-env; cpu_reset(env); -env-active_tc.PC = s-vector; +env-active_tc.PC = s-vector ~(target_ulong)1; +if (s-vector 1) { +env-hflags |= MIPS_HFLAG_M16; +} } static void -- 1.6.3.2
[Qemu-devel] [PATCH 2/8] target-mips: refactor c{, abs}.cond.fmt insns
Move all knowledge about coprocessor-checking and register numbering into the gen_cmp* helper functions. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate.c | 164 +++ 1 files changed, 81 insertions(+), 83 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 4e54940..8d532d5 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -676,39 +676,6 @@ static inline int get_fp_bit (int cc) return 23; } -#define FOP_CONDS(type, fmt, bits)\ -static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a, \ - TCGv_i##bits b, int cc)\ -{ \ -switch (n) { \ -case 0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);break;\ -case 1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc); break;\ -case 2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc); break;\ -case 3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc); break;\ -case 4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc); break;\ -case 5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc); break;\ -case 6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc); break;\ -case 7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc); break;\ -case 8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc); break;\ -case 9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\ -case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc); break;\ -case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc); break;\ -case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc); break;\ -case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc); break;\ -case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc); break;\ -case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc); break;\ -default: abort(); \ -} \ -} - -FOP_CONDS(, d, 64) -FOP_CONDS(abs, d, 64) -FOP_CONDS(, s, 32) -FOP_CONDS(abs, s, 32) -FOP_CONDS(, ps, 64) -FOP_CONDS(abs, ps, 64) -#undef FOP_CONDS - /* Tests */ static inline void gen_save_pc(target_ulong pc) { @@ -849,6 +816,69 @@ static inline void check_mips_64(DisasContext *ctx) generate_exception(ctx, EXCP_RI); } +/* Define small wrappers for gen_load_fpr* so that we have a uniform + calling interface for 32 and 64-bit FPRs. No sense in changing + all callers for gen_load_fpr32 when we need the CTX parameter for + this one use. */ +#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y) +#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) +#define FOP_CONDS(type, abs, fmt, ifmt, bits) \ +static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ + int ft, int fs, int cc)\ +{ \ +TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \ +TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \ +switch (ifmt) { \ +case FMT_PS: \ +check_cp1_64bitmode(ctx); \ +break;\ +case FMT_D: \ +if (abs) {\ +check_cop1x(ctx); \ +} \ +check_cp1_registers(ctx, fs | ft);\ +break;\ +case FMT_S: \ +if (abs) {\ +check_cop1x(ctx); \ +} \ +break;\ +} \ +gen_ldcmp_fpr##bits (ctx, fp0, fs); \ +gen_ldcmp_fpr##bits (ctx, fp1, ft
[Qemu-devel] [PATCH 1/8] target-mips: define constants for magic numbers
Add FMT_* constants for the floating-point format field in opcodes and tweak a few places to use them. Add enums for various invocations of FOP and tweak gen_farith and its lone caller accordingly. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate.c | 437 --- 1 files changed, 295 insertions(+), 142 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 2075d09..4e54940 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -354,6 +354,19 @@ enum { /* Coprocessor 1 (rs field) */ #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op (0x1F 21)) +/* Values for the fmt field in FP instructions */ +enum { +/* 0 - 15 are reserved */ +FMT_S = 16, +FMT_D = 17, +FMT_E = 18, +FMT_Q = 19, +FMT_W = 20, +FMT_L = 21, +FMT_PS = 22, +/* 23 - 31 are reserved */ +}; + enum { OPC_MFC1 = (0x00 21) | OPC_CP1, OPC_DMFC1= (0x01 21) | OPC_CP1, @@ -366,13 +379,13 @@ enum { OPC_BC1 = (0x08 21) | OPC_CP1, /* bc */ OPC_BC1ANY2 = (0x09 21) | OPC_CP1, OPC_BC1ANY4 = (0x0A 21) | OPC_CP1, -OPC_S_FMT= (0x10 21) | OPC_CP1, /* 16: fmt=single fp */ -OPC_D_FMT= (0x11 21) | OPC_CP1, /* 17: fmt=double fp */ -OPC_E_FMT= (0x12 21) | OPC_CP1, /* 18: fmt=extended fp */ -OPC_Q_FMT= (0x13 21) | OPC_CP1, /* 19: fmt=quad fp */ -OPC_W_FMT= (0x14 21) | OPC_CP1, /* 20: fmt=32bit fixed */ -OPC_L_FMT= (0x15 21) | OPC_CP1, /* 21: fmt=64bit fixed */ -OPC_PS_FMT = (0x16 21) | OPC_CP1, /* 22: fmt=paired single fp */ +OPC_S_FMT= (FMT_S 21) | OPC_CP1, /* 16: fmt=single fp */ +OPC_D_FMT= (FMT_D 21) | OPC_CP1, /* 17: fmt=double fp */ +OPC_E_FMT= (FMT_E 21) | OPC_CP1, /* 18: fmt=extended fp */ +OPC_Q_FMT= (FMT_Q 21) | OPC_CP1, /* 19: fmt=quad fp */ +OPC_W_FMT= (FMT_W 21) | OPC_CP1, /* 20: fmt=32bit fixed */ +OPC_L_FMT= (FMT_L 21) | OPC_CP1, /* 21: fmt=64bit fixed */ +OPC_PS_FMT = (FMT_PS 21) | OPC_CP1, /* 22: fmt=paired single fp */ }; #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op 0x3F) @@ -5714,6 +5727,146 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, #define FOP(func, fmt) (((fmt) 21) | (func)) +enum fopcode { +OPC_ADD_S = FOP(0, FMT_S), +OPC_SUB_S = FOP(1, FMT_S), +OPC_MUL_S = FOP(2, FMT_S), +OPC_DIV_S = FOP(3, FMT_S), +OPC_SQRT_S = FOP(4, FMT_S), +OPC_ABS_S = FOP(5, FMT_S), +OPC_MOV_S = FOP(6, FMT_S), +OPC_NEG_S = FOP(7, FMT_S), +OPC_ROUND_L_S = FOP(8, FMT_S), +OPC_TRUNC_L_S = FOP(9, FMT_S), +OPC_CEIL_L_S = FOP(10, FMT_S), +OPC_FLOOR_L_S = FOP(11, FMT_S), +OPC_ROUND_W_S = FOP(12, FMT_S), +OPC_TRUNC_W_S = FOP(13, FMT_S), +OPC_CEIL_W_S = FOP(14, FMT_S), +OPC_FLOOR_W_S = FOP(15, FMT_S), +OPC_MOVCF_S = FOP(17, FMT_S), +OPC_MOVZ_S = FOP(18, FMT_S), +OPC_MOVN_S = FOP(19, FMT_S), +OPC_RECIP_S = FOP(21, FMT_S), +OPC_RSQRT_S = FOP(22, FMT_S), +OPC_RECIP2_S = FOP(28, FMT_S), +OPC_RECIP1_S = FOP(29, FMT_S), +OPC_RSQRT1_S = FOP(30, FMT_S), +OPC_RSQRT2_S = FOP(31, FMT_S), +OPC_CVT_D_S = FOP(33, FMT_S), +OPC_CVT_W_S = FOP(36, FMT_S), +OPC_CVT_L_S = FOP(37, FMT_S), +OPC_CVT_PS_S = FOP(38, FMT_S), +OPC_CMP_F_S = FOP (48, FMT_S), +OPC_CMP_UN_S = FOP (49, FMT_S), +OPC_CMP_EQ_S = FOP (50, FMT_S), +OPC_CMP_UEQ_S = FOP (51, FMT_S), +OPC_CMP_OLT_S = FOP (52, FMT_S), +OPC_CMP_ULT_S = FOP (53, FMT_S), +OPC_CMP_OLE_S = FOP (54, FMT_S), +OPC_CMP_ULE_S = FOP (55, FMT_S), +OPC_CMP_SF_S = FOP (56, FMT_S), +OPC_CMP_NGLE_S = FOP (57, FMT_S), +OPC_CMP_SEQ_S = FOP (58, FMT_S), +OPC_CMP_NGL_S = FOP (59, FMT_S), +OPC_CMP_LT_S = FOP (60, FMT_S), +OPC_CMP_NGE_S = FOP (61, FMT_S), +OPC_CMP_LE_S = FOP (62, FMT_S), +OPC_CMP_NGT_S = FOP (63, FMT_S), + +OPC_ADD_D = FOP(0, FMT_D), +OPC_SUB_D = FOP(1, FMT_D), +OPC_MUL_D = FOP(2, FMT_D), +OPC_DIV_D = FOP(3, FMT_D), +OPC_SQRT_D = FOP(4, FMT_D), +OPC_ABS_D = FOP(5, FMT_D), +OPC_MOV_D = FOP(6, FMT_D), +OPC_NEG_D = FOP(7, FMT_D), +OPC_ROUND_L_D = FOP(8, FMT_D), +OPC_TRUNC_L_D = FOP(9, FMT_D), +OPC_CEIL_L_D = FOP(10, FMT_D), +OPC_FLOOR_L_D = FOP(11, FMT_D), +OPC_ROUND_W_D = FOP(12, FMT_D), +OPC_TRUNC_W_D = FOP(13, FMT_D), +OPC_CEIL_W_D = FOP(14, FMT_D), +OPC_FLOOR_W_D = FOP(15, FMT_D), +OPC_MOVCF_D = FOP(17, FMT_D), +OPC_MOVZ_D = FOP(18, FMT_D), +OPC_MOVN_D = FOP(19, FMT_D), +OPC_RECIP_D = FOP(21, FMT_D), +OPC_RSQRT_D = FOP(22, FMT_D), +OPC_RECIP2_D = FOP(28, FMT_D), +OPC_RECIP1_D = FOP(29, FMT_D), +OPC_RSQRT1_D = FOP(30, FMT_D), +OPC_RSQRT2_D = FOP(31, FMT_D), +OPC_CVT_S_D = FOP(32, FMT_D), +OPC_CVT_W_D = FOP(36, FMT_D), +OPC_CVT_L_D = FOP(37, FMT_D), +OPC_CMP_F_D = FOP (48, FMT_D
[Qemu-devel] [PATCH 3/8] target-mips: mips16 cleanups
Change code handling mips16-specific branches to use ISA-neutral special opcodes. Since there are several places where the delay slot requirements for microMIPS branches differ from mips16 branches, using opcodes is easier than checking hflags, then checking mips16 vs. microMIPS. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate.c | 24 +--- 1 files changed, 17 insertions(+), 7 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 8d532d5..2754b2e 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -68,6 +68,7 @@ enum { /* Jump and branches */ OPC_J= (0x02 26), OPC_JAL = (0x03 26), +OPC_JALS = OPC_JAL | 0x5, OPC_BEQ = (0x04 26), /* Unconditional if rs = rt = 0 (B) */ OPC_BEQL = (0x14 26), OPC_BNE = (0x05 26), @@ -77,6 +78,7 @@ enum { OPC_BGTZ = (0x07 26), OPC_BGTZL= (0x17 26), OPC_JALX = (0x1D 26), /* MIPS 16 only */ +OPC_JALXS= OPC_JALX | 0x5, /* Load and stores */ OPC_LDL = (0x1A 26), OPC_LDR = (0x1B 26), @@ -177,6 +179,7 @@ enum { OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ OPC_JALRC= OPC_JALR | (0x5 6), +OPC_JALRS= 0x10 | OPC_SPECIAL | (0x5 6), /* Traps */ OPC_TGE = 0x30 | OPC_SPECIAL, OPC_TGEU = 0x31 | OPC_SPECIAL, @@ -2466,12 +2469,15 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, case OPC_J: case OPC_JAL: case OPC_JALX: +case OPC_JALS: +case OPC_JALXS: /* Jump to immediate */ btgt = ((ctx-pc + insn_bytes) (int32_t)0xF000) | (uint32_t)offset; break; case OPC_JR: case OPC_JALR: case OPC_JALRC: +case OPC_JALRS: /* Jump to register */ if (offset != 0 offset != 16) { /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the @@ -2534,29 +2540,33 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, ctx-hflags |= MIPS_HFLAG_B; MIPS_DEBUG(j TARGET_FMT_lx, btgt); break; +case OPC_JALXS: case OPC_JALX: ctx-hflags |= MIPS_HFLAG_BX; /* Fallthrough */ +case OPC_JALS: case OPC_JAL: blink = 31; ctx-hflags |= MIPS_HFLAG_B; -ctx-hflags |= (ctx-hflags MIPS_HFLAG_M16 +ctx-hflags |= ((opc == OPC_JALS || opc == OPC_JALXS) ? MIPS_HFLAG_BDS16 : MIPS_HFLAG_BDS32); MIPS_DEBUG(jal TARGET_FMT_lx, btgt); break; case OPC_JR: ctx-hflags |= MIPS_HFLAG_BR; -if (ctx-hflags MIPS_HFLAG_M16) -ctx-hflags |= MIPS_HFLAG_BDS16; +if (insn_bytes == 4) +ctx-hflags |= MIPS_HFLAG_BDS32; MIPS_DEBUG(jr %s, regnames[rs]); break; +case OPC_JALRS: case OPC_JALR: case OPC_JALRC: blink = rt; ctx-hflags |= MIPS_HFLAG_BR; -if (ctx-hflags MIPS_HFLAG_M16) -ctx-hflags |= MIPS_HFLAG_BDS16; +ctx-hflags |= (opc == OPC_JALRS +? MIPS_HFLAG_BDS16 +: MIPS_HFLAG_BDS32); MIPS_DEBUG(jalr %s, %s, regnames[rt], regnames[rs]); break; default: @@ -8487,7 +8497,7 @@ static int decode_mips16_opc (CPUState *env, DisasContext *ctx, offset = (((ctx-opcode 0x1f) 21) | ((ctx-opcode 5) 0x1f) 16 | offset) 2; -op = ((ctx-opcode 10) 0x1) ? OPC_JALX : OPC_JAL; +op = ((ctx-opcode 10) 0x1) ? OPC_JALXS : OPC_JALS; gen_compute_branch(ctx, op, 4, rx, ry, offset); n_bytes = 4; *is_branch = 1; @@ -8726,7 +8736,7 @@ static int decode_mips16_opc (CPUState *env, DisasContext *ctx, int ra = (ctx-opcode 5) 0x1; if (link) { -op = nd ? OPC_JALRC : OPC_JALR; +op = nd ? OPC_JALRC : OPC_JALRS; } else { op = OPC_JR; } -- 1.6.3.2
[Qemu-devel] [PATCH 6/8] target-mips: add microMIPS exception handler support
Unlike MIPS16, microMIPS lets you choose the ISA mode for your exception handlers. The ISA mode is selectable via a user-writable CP0.Config3 flag. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/cpu.h|1 + target-mips/helper.c | 21 +++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 7285636..c21b8e4 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -363,6 +363,7 @@ struct CPUMIPSState { #define CP0C2_SA 0 int32_t CP0_Config3; #define CP0C3_M31 +#define CP0C3_ISA_ON_EXC 16 #define CP0C3_DSPP 10 #define CP0C3_LPA 7 #define CP0C3_VEIC 6 diff --git a/target-mips/helper.c b/target-mips/helper.c index 8102f03..ea221ab 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -385,6 +385,18 @@ static target_ulong exception_resume_pc (CPUState *env) return bad_pc; } + +static void set_hflags_for_handler (CPUState *env) +{ +/* Exception handlers are entered in 32-bit mode. */ +env-hflags = ~(MIPS_HFLAG_M16); +/* ...except that microMIPS lets you choose. */ +if (env-insn_flags ASE_MICROMIPS) { +env-hflags |= (!!(env-CP0_Config3 +(1 CP0C3_ISA_ON_EXC)) + MIPS_HFLAG_M16_SHIFT); +} +} #endif void do_interrupt (CPUState *env) @@ -440,8 +452,7 @@ void do_interrupt (CPUState *env) if (!(env-CP0_Status (1 CP0St_EXL))) env-CP0_Cause = ~(1 CP0Ca_BD); env-active_tc.PC = (int32_t)0xBFC00480; -/* Exception handlers are entered in 32-bit mode. */ -env-hflags = ~(MIPS_HFLAG_M16); +set_hflags_for_handler(env); break; case EXCP_RESET: cpu_reset(env); @@ -461,8 +472,7 @@ void do_interrupt (CPUState *env) if (!(env-CP0_Status (1 CP0St_EXL))) env-CP0_Cause = ~(1 CP0Ca_BD); env-active_tc.PC = (int32_t)0xBFC0; -/* Exception handlers are entered in 32-bit mode. */ -env-hflags = ~(MIPS_HFLAG_M16); +set_hflags_for_handler(env); break; case EXCP_EXT_INTERRUPT: cause = 0; @@ -581,8 +591,7 @@ void do_interrupt (CPUState *env) env-active_tc.PC = (int32_t)(env-CP0_EBase ~0x3ff); } env-active_tc.PC += offset; -/* Exception handlers are entered in 32-bit mode. */ -env-hflags = ~(MIPS_HFLAG_M16); +set_hflags_for_handler(env); env-CP0_Cause = (env-CP0_Cause ~(0x1f CP0Ca_EC)) | (cause CP0Ca_EC); break; default: -- 1.6.3.2
[Qemu-devel] [PATCH 5/8] target-mips: add microMIPS CPUs
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate_init.c | 61 ++ 1 files changed, 61 insertions(+), 0 deletions(-) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index b79ed56..8e17f4b 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -141,6 +141,25 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_FMT, }, { +.name = 4Km-micromips, +.CP0_PRid = 0x00018300, +/* Config1 implemented, fixed mapping MMU, + no virtual icache, uncached coherency. */ +.CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | + (0 CP0C1_IS) | (3 CP0C1_IL) | (1 CP0C1_IA) | + (0 CP0C1_DS) | (3 CP0C1_DL) | (1 CP0C1_DA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3, +.SYNCI_Step = 32, +.CCRes = 2, +.CP0_Status_rw_bitmask = 0x1258FF17, +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, +.mmu_type = MMU_TYPE_FMT, +}, +{ .name = 4KEcR1, .CP0_PRid = 0x00018400, .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 CP0C0_MT), @@ -245,6 +264,25 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +.name = 24Kc-micromips, +.CP0_PRid = 0x00019300, +.CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | +(MMU_TYPE_R4000 CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | (15 CP0C1_MMU) | + (0 CP0C1_IS) | (3 CP0C1_IL) | (1 CP0C1_IA) | + (0 CP0C1_DS) | (3 CP0C1_DL) | (1 CP0C1_DA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3 | (0 CP0C3_VInt), +.SYNCI_Step = 32, +.CCRes = 2, +/* No DSP implemented. */ +.CP0_Status_rw_bitmask = 0x1278FF1F, +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, +.mmu_type = MMU_TYPE_R4000, +}, +{ .name = 24Kf, .CP0_PRid = 0x00019300, .CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | @@ -269,6 +307,29 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +.name = 24Kf-micromips, +.CP0_PRid = 0x00019300, +.CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | +(MMU_TYPE_R4000 CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | (1 CP0C1_FP) | (15 CP0C1_MMU) | + (0 CP0C1_IS) | (3 CP0C1_IL) | (1 CP0C1_IA) | + (0 CP0C1_DS) | (3 CP0C1_DL) | (1 CP0C1_DA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3 | (0 CP0C3_VInt), +.CP0_LLAddr_rw_bitmask = 0, +.CP0_LLAddr_shift = 4, +.SYNCI_Step = 32, +.CCRes = 2, +/* No DSP implemented. */ +.CP0_Status_rw_bitmask = 0x3678FF1F, +.CP1_fcr0 = (1 FCR0_F64) | (1 FCR0_L) | (1 FCR0_W) | +(1 FCR0_D) | (1 FCR0_S) | (0x93 FCR0_PRID), +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, +.mmu_type = MMU_TYPE_R4000, +}, +{ .name = 34Kf, .CP0_PRid = 0x00019500, .CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | -- 1.6.3.2
Re: [Qemu-devel] [PATCH 00/10] target-mips: add microMIPS ASE support, v2
On Mon, May 24, 2010 at 09:19:34AM -0700, Nathan Froyd wrote: This patch series adds support for the microMIPS ASE. microMIPS is a new ASE similar to MIPS16, but re-encodes the entire instruction set into 16-bit and 32-bit instructions--in contrast to MIPS16, which re-encodes only integer instructions. The mechanisms for going in and out of microMIPS mode are identical to those for MIPS16; a given chip cannot support both ASEs simultaneously. Ping. -Nathan
Re: [Qemu-devel] [PATCH 03/10] target-mips: add enum constants for various invocations of FOP
On Fri, Jun 04, 2010 at 10:45:32AM -0700, Richard Henderson wrote: On 05/24/2010 09:19 AM, Nathan Froyd wrote: @@ -5937,8 +6031,8 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP; uint32_t func = ctx-opcode 0x3f; -switch (ctx-opcode FOP(0x3f, 0x1f)) { -case FOP(0, 16): +switch (opc) { +case OPC_ADD_S: For instance, opc would seem to be a good candidate for a variable to be switched to the enumeration type. ... Except that I can't seem to find the definition of opc at this point in patch 3? It looks like the argument op1 should be what's used here. Is this a case of patches being split incorrectly? This is indeed supposed to be op1; the typo gets fixed in patch 6. What's the benefit from declaring op1 as 'enum fopcode' or similar? -Nathan
Re: [Qemu-devel] [PATCH 06/10] target-mips: add microMIPS ASE support
On Fri, Jun 04, 2010 at 11:30:38AM -0700, Richard Henderson wrote: On 05/24/2010 09:19 AM, Nathan Froyd wrote: +int (*ldfun)(target_ulong); + +switch (mem_idx) +{ +case 0: ldfun = ldl_kernel; break; +case 1: ldfun = ldl_super; break; +default: +case 2: ldfun = ldl_user; break; +} This *should* now be a compile error. The return type should now be uint32_t, not int. Will fix, thanks for pointing that out. @@ -2535,26 +2555,29 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, case OPC_JALX: ctx-hflags |= MIPS_HFLAG_BX; /* Fallthrough */ +case OPC_JALS: case OPC_JAL: blink = 31; ctx-hflags |= MIPS_HFLAG_B; -ctx-hflags |= (ctx-hflags MIPS_HFLAG_M16 +ctx-hflags |= (opc == OPC_JALS ? MIPS_HFLAG_BDS16 : MIPS_HFLAG_BDS32); Changed semantics here? You're no longer testing M16 bit. Or is that later handled by switching mips16 to JALS too? It ought to be handled by switching mips16 to use JALS. I see that I didn't do that. And if so, perhaps this patch should be broken into two, where you introduce the new opcodes and hflags changes and apply them as-needed to the mips16 code. Thus one can verify that the semantics for mips16 are the same before and after. I don't think there are any hflags changes, but the point is well-taken. I'll do that. +if (base == 0) { +tcg_gen_movi_tl(t0, 0); +} else { +gen_load_gpr(t0, base); +} gen_load_gpr already takes care of R0. Will fix. +#if 0 +case 0x01: +switch (minor) { +case MFHI_ACC: +gen_HILO(ctx, OPC_MFHI, rs); New if 0 code? Yup, will delete. -Nathan
Re: [Qemu-devel] [PATCH 07/10] target-mips: add microMIPS CPUs
On Fri, Jun 04, 2010 at 11:35:45AM -0700, Richard Henderson wrote: On 05/24/2010 09:19 AM, Nathan Froyd wrote: Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate_init.c | 61 ++ 1 files changed, 61 insertions(+), 0 deletions(-) Reviewed-by: Richard Henderson r...@twiddle.net ... not that there's anything in here I could actually verify without hardware manuals ;-) :) For avoidance of doubt, the 24K*micromips variants were added for easy testing initially; the 4Km-micromips definition is actually based on real hardware. I'm happy to just submit the one based on real hardware if that would be easier. -Nathan
[Qemu-devel] [PATCH 02/10] target-mips: add microMIPS-specific bits to mips-defs.h
There's a new ASE_MICROMIPS instruction flag, and some extra CP0_Config3 fields. The ISA and ISA_ON_EXC fields are specific to microMIPS. The DSP2P is for version 2 of the DSP ASE. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/cpu.h |3 +++ target-mips/mips-defs.h |1 + 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 7285636..986d938 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -363,6 +363,9 @@ struct CPUMIPSState { #define CP0C2_SA 0 int32_t CP0_Config3; #define CP0C3_M31 +#define CP0C3_ISA_ON_EXC 16 +#define CP0C3_ISA 14 +#define CP0C3_DSP2P 11 #define CP0C3_DSPP 10 #define CP0C3_LPA 7 #define CP0C3_VEIC 6 diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h index c57de02..a7f4697 100644 --- a/target-mips/mips-defs.h +++ b/target-mips/mips-defs.h @@ -38,6 +38,7 @@ #defineASE_DSPR2 0x0001 #defineASE_MT 0x0002 #defineASE_SMARTMIPS 0x0004 +#defineASE_MICROMIPS 0x0008 /* Chip specific instructions. */ #defineINSN_VR54XX 0x8000 -- 1.6.3.2
[Qemu-devel] [PATCH 03/10] target-mips: add enum constants for various invocations of FOP
Tweak gen_farith and its caller to use them. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate.c | 266 --- 1 files changed, 180 insertions(+), 86 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 2075d09..2568e16 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -5714,6 +5714,100 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, #define FOP(func, fmt) (((fmt) 21) | (func)) +enum { +OPC_ADD_S = FOP(0, FMT_S), +OPC_SUB_S = FOP(1, FMT_S), +OPC_MUL_S = FOP(2, FMT_S), +OPC_DIV_S = FOP(3, FMT_S), +OPC_SQRT_S = FOP(4, FMT_S), +OPC_ABS_S = FOP(5, FMT_S), +OPC_MOV_S = FOP(6, FMT_S), +OPC_NEG_S = FOP(7, FMT_S), +OPC_ROUND_L_S = FOP(8, FMT_S), +OPC_TRUNC_L_S = FOP(9, FMT_S), +OPC_CEIL_L_S = FOP(10, FMT_S), +OPC_FLOOR_L_S = FOP(11, FMT_S), +OPC_ROUND_W_S = FOP(12, FMT_S), +OPC_TRUNC_W_S = FOP(13, FMT_S), +OPC_CEIL_W_S = FOP(14, FMT_S), +OPC_FLOOR_W_S = FOP(15, FMT_S), +OPC_MOVCF_S = FOP(17, FMT_S), +OPC_MOVZ_S = FOP(18, FMT_S), +OPC_MOVN_S = FOP(19, FMT_S), +OPC_RECIP_S = FOP(21, FMT_S), +OPC_RSQRT_S = FOP(22, FMT_S), +OPC_RECIP2_S = FOP(28, FMT_S), +OPC_RECIP1_S = FOP(29, FMT_S), +OPC_RSQRT1_S = FOP(30, FMT_S), +OPC_RSQRT2_S = FOP(31, FMT_S), +OPC_CVT_D_S = FOP(33, FMT_S), +OPC_CVT_W_S = FOP(36, FMT_S), +OPC_CVT_L_S = FOP(37, FMT_S), +OPC_CVT_PS_S = FOP(38, FMT_S), +/* FOP(48..63, FMT_S) used for comparisons */ +OPC_ADD_D = FOP(0, FMT_D), +OPC_SUB_D = FOP(1, FMT_D), +OPC_MUL_D = FOP(2, FMT_D), +OPC_DIV_D = FOP(3, FMT_D), +OPC_SQRT_D = FOP(4, FMT_D), +OPC_ABS_D = FOP(5, FMT_D), +OPC_MOV_D = FOP(6, FMT_D), +OPC_NEG_D = FOP(7, FMT_D), +OPC_ROUND_L_D = FOP(8, FMT_D), +OPC_TRUNC_L_D = FOP(9, FMT_D), +OPC_CEIL_L_D = FOP(10, FMT_D), +OPC_FLOOR_L_D = FOP(11, FMT_D), +OPC_ROUND_W_D = FOP(12, FMT_D), +OPC_TRUNC_W_D = FOP(13, FMT_D), +OPC_CEIL_W_D = FOP(14, FMT_D), +OPC_FLOOR_W_D = FOP(15, FMT_D), +OPC_MOVCF_D = FOP(17, FMT_D), +OPC_MOVZ_D = FOP(18, FMT_D), +OPC_MOVN_D = FOP(19, FMT_D), +OPC_RECIP_D = FOP(21, FMT_D), +OPC_RSQRT_D = FOP(22, FMT_D), +OPC_RECIP2_D = FOP(28, FMT_D), +OPC_RECIP1_D = FOP(29, FMT_D), +OPC_RSQRT1_D = FOP(30, FMT_D), +OPC_RSQRT2_D = FOP(31, FMT_D), +OPC_CVT_S_D = FOP(32, FMT_D), +OPC_CVT_W_D = FOP(36, FMT_D), +OPC_CVT_L_D = FOP(37, FMT_D), +/* FOP(48..63, FMT_D) used for comparisons */ + +OPC_CVT_S_W = FOP(32, FMT_W), +OPC_CVT_D_W = FOP(33, FMT_W), +OPC_CVT_S_L = FOP(32, FMT_L), +OPC_CVT_D_L = FOP(33, FMT_L), +OPC_CVT_PS_PW = FOP(38, FMT_W), + +OPC_ADD_PS = FOP(0, FMT_PS), +OPC_SUB_PS = FOP(1, FMT_PS), +OPC_MUL_PS = FOP(2, FMT_PS), +OPC_DIV_PS = FOP(3, FMT_PS), +OPC_ABS_PS = FOP(5, FMT_PS), +OPC_MOV_PS = FOP(6, FMT_PS), +OPC_NEG_PS = FOP(7, FMT_PS), +OPC_MOVCF_PS = FOP(17, FMT_PS), +OPC_MOVZ_PS = FOP(18, FMT_PS), +OPC_MOVN_PS = FOP(19, FMT_PS), +OPC_ADDR_PS = FOP(24, FMT_PS), +OPC_MULR_PS = FOP(26, FMT_PS), +OPC_RECIP2_PS = FOP(28, FMT_PS), +OPC_RECIP1_PS = FOP(29, FMT_PS), +OPC_RSQRT1_PS = FOP(30, FMT_PS), +OPC_RSQRT2_PS = FOP(31, FMT_PS), + +OPC_CVT_S_PU = FOP(32, FMT_PS), +OPC_CVT_PW_PS = FOP(36, FMT_PS), +OPC_CVT_S_PL = FOP(40, FMT_PS), +OPC_PLL_PS = FOP(44, FMT_PS), +OPC_PLU_PS = FOP(45, FMT_PS), +OPC_PUL_PS = FOP(46, FMT_PS), +OPC_PUU_PS = FOP(47, FMT_PS), +/* FOP(48..63, FMT_PS) used for comparisons */ +}; + static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) { const char *opn = cp1 move; @@ -5937,8 +6031,8 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP; uint32_t func = ctx-opcode 0x3f; -switch (ctx-opcode FOP(0x3f, 0x1f)) { -case FOP(0, 16): +switch (opc) { +case OPC_ADD_S: { TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); @@ -5953,7 +6047,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, opn = add.s; optype = BINOP; break; -case FOP(1, 16): +case OPC_SUB_S: { TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); @@ -5968,7 +6062,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, opn = sub.s; optype = BINOP; break; -case FOP(2, 16): +case OPC_MUL_S: { TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); @@ -5983,7 +6077,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, opn = mul.s; optype = BINOP; break; -case FOP(3, 16): +case OPC_DIV_S: { TCGv_i32 fp0
[Qemu-devel] [PATCH 01/10] target-mips: break out [ls][wd]c1 and rdhwr insn generation
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate.c | 106 ++- 1 files changed, 59 insertions(+), 47 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index c95ecb1..2075d09 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1220,6 +1220,17 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, tcg_temp_free(t0); } +static void gen_cop1_ldst(CPUState *env, DisasContext *ctx, + uint32_t op, int rt, int rs, int16_t imm) +{ +if (env-CP0_Config1 (1 CP0C1_FP)) { +check_cp1_enabled(ctx); +gen_flt_ldst(ctx, op, rt, rs, imm); +} else { +generate_exception_err(ctx, EXCP_CpU, 1); +} +} + /* Arithmetic with immediate operand */ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rs, int16_t imm) @@ -7528,6 +7539,52 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, fregnames[fs], fregnames[ft]); } +static void +gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd) +{ +TCGv t0; + +check_insn(env, ctx, ISA_MIPS32R2); +t0 = tcg_temp_new(); + +switch (rd) { +case 0: +save_cpu_state(ctx, 1); +gen_helper_rdhwr_cpunum(t0); +gen_store_gpr(t0, rt); +break; +case 1: +save_cpu_state(ctx, 1); +gen_helper_rdhwr_synci_step(t0); +gen_store_gpr(t0, rt); +break; +case 2: +save_cpu_state(ctx, 1); +gen_helper_rdhwr_cc(t0); +gen_store_gpr(t0, rt); +break; +case 3: +save_cpu_state(ctx, 1); +gen_helper_rdhwr_ccres(t0); +gen_store_gpr(t0, rt); +break; +case 29: +#if defined(CONFIG_USER_ONLY) +tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); +gen_store_gpr(t0, rt); +break; +#else +/* XXX: Some CPUs implement this in hardware. + Not supported yet. */ +#endif +default:/* Invalid */ +MIPS_INVAL(rdhwr); +generate_exception(ctx, EXCP_RI); +break; +} +tcg_temp_free(t0); +} + static void handle_delay_slot (CPUState *env, DisasContext *ctx, int insn_bytes) { @@ -8999,47 +9056,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch) gen_bshfl(ctx, op2, rt, rd); break; case OPC_RDHWR: -check_insn(env, ctx, ISA_MIPS32R2); -{ -TCGv t0 = tcg_temp_new(); - -switch (rd) { -case 0: -save_cpu_state(ctx, 1); -gen_helper_rdhwr_cpunum(t0); -gen_store_gpr(t0, rt); -break; -case 1: -save_cpu_state(ctx, 1); -gen_helper_rdhwr_synci_step(t0); -gen_store_gpr(t0, rt); -break; -case 2: -save_cpu_state(ctx, 1); -gen_helper_rdhwr_cc(t0); -gen_store_gpr(t0, rt); -break; -case 3: -save_cpu_state(ctx, 1); -gen_helper_rdhwr_ccres(t0); -gen_store_gpr(t0, rt); -break; -case 29: -#if defined(CONFIG_USER_ONLY) -tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); -gen_store_gpr(t0, rt); -break; -#else -/* XXX: Some CPUs implement this in hardware. - Not supported yet. */ -#endif -default:/* Invalid */ -MIPS_INVAL(rdhwr); -generate_exception(ctx, EXCP_RI); -break; -} -tcg_temp_free(t0); -} +gen_rdhwr(env, ctx, rt, rd); break; case OPC_FORK: check_insn(env, ctx, ASE_MT); @@ -9242,12 +9259,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch) case OPC_LDC1: case OPC_SWC1: case OPC_SDC1: -if (env-CP0_Config1 (1 CP0C1_FP)) { -check_cp1_enabled(ctx); -gen_flt_ldst(ctx, op, rt, rs, imm); -} else { -generate_exception_err(ctx, EXCP_CpU, 1); -} +gen_cop1_ldst(env, ctx, op, rt, rs, imm); break; case OPC_CP1: -- 1.6.3.2
[Qemu-devel] [PATCH 05/10] target-mips: small changes to use new FMT_ enums
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate.c | 17 + 1 files changed, 9 insertions(+), 8 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 63844b8..cc445fb 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -359,7 +359,8 @@ enum { /* 0 - 15 are reserved */ FMT_S = 16, FMT_D = 17, -/* 18 - 19 are reserved */ +FMT_E = 18, +FMT_Q = 19, FMT_W = 20, FMT_L = 21, FMT_PS = 22, @@ -378,13 +379,13 @@ enum { OPC_BC1 = (0x08 21) | OPC_CP1, /* bc */ OPC_BC1ANY2 = (0x09 21) | OPC_CP1, OPC_BC1ANY4 = (0x0A 21) | OPC_CP1, -OPC_S_FMT= (0x10 21) | OPC_CP1, /* 16: fmt=single fp */ -OPC_D_FMT= (0x11 21) | OPC_CP1, /* 17: fmt=double fp */ -OPC_E_FMT= (0x12 21) | OPC_CP1, /* 18: fmt=extended fp */ -OPC_Q_FMT= (0x13 21) | OPC_CP1, /* 19: fmt=quad fp */ -OPC_W_FMT= (0x14 21) | OPC_CP1, /* 20: fmt=32bit fixed */ -OPC_L_FMT= (0x15 21) | OPC_CP1, /* 21: fmt=64bit fixed */ -OPC_PS_FMT = (0x16 21) | OPC_CP1, /* 22: fmt=paired single fp */ +OPC_S_FMT= (FMT_S 21) | OPC_CP1, /* 16: fmt=single fp */ +OPC_D_FMT= (FMT_D 21) | OPC_CP1, /* 17: fmt=double fp */ +OPC_E_FMT= (FMT_E 21) | OPC_CP1, /* 18: fmt=extended fp */ +OPC_Q_FMT= (FMT_Q 21) | OPC_CP1, /* 19: fmt=quad fp */ +OPC_W_FMT= (FMT_W 21) | OPC_CP1, /* 20: fmt=32bit fixed */ +OPC_L_FMT= (FMT_L 21) | OPC_CP1, /* 21: fmt=64bit fixed */ +OPC_PS_FMT = (FMT_PS 21) | OPC_CP1, /* 22: fmt=paired single fp */ }; #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op 0x3F) -- 1.6.3.2
[Qemu-devel] [PATCH 04/10] target-mips: refactor {c, abs}.cond.fmt insns
Move all knowledge about coprocessor-checking and register numbering into the gen_cmp* helper functions. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate.c | 174 -- 1 files changed, 91 insertions(+), 83 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 2568e16..63844b8 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -354,6 +354,18 @@ enum { /* Coprocessor 1 (rs field) */ #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op (0x1F 21)) +/* Values for the fmt field in FP instructions */ +enum { +/* 0 - 15 are reserved */ +FMT_S = 16, +FMT_D = 17, +/* 18 - 19 are reserved */ +FMT_W = 20, +FMT_L = 21, +FMT_PS = 22, +/* 23 - 31 are reserved */ +}; + enum { OPC_MFC1 = (0x00 21) | OPC_CP1, OPC_DMFC1= (0x01 21) | OPC_CP1, @@ -663,39 +675,6 @@ static inline int get_fp_bit (int cc) return 23; } -#define FOP_CONDS(type, fmt, bits)\ -static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a, \ - TCGv_i##bits b, int cc)\ -{ \ -switch (n) { \ -case 0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);break;\ -case 1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc); break;\ -case 2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc); break;\ -case 3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc); break;\ -case 4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc); break;\ -case 5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc); break;\ -case 6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc); break;\ -case 7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc); break;\ -case 8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc); break;\ -case 9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\ -case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc); break;\ -case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc); break;\ -case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc); break;\ -case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc); break;\ -case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc); break;\ -case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc); break;\ -default: abort(); \ -} \ -} - -FOP_CONDS(, d, 64) -FOP_CONDS(abs, d, 64) -FOP_CONDS(, s, 32) -FOP_CONDS(abs, s, 32) -FOP_CONDS(, ps, 64) -FOP_CONDS(abs, ps, 64) -#undef FOP_CONDS - /* Tests */ static inline void gen_save_pc(target_ulong pc) { @@ -836,6 +815,67 @@ static inline void check_mips_64(DisasContext *ctx) generate_exception(ctx, EXCP_RI); } +/* Define small wrappers for gen_load_fpr* so that we have a uniform + calling interface for 32 and 64-bit FPRs. No sense in changing + all callers for gen_load_fpr32 when we need the CTX parameter for + this one use. */ +#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y) +#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) +#define FOP_CONDS(type, abs, fmt, ifmt, bits) \ +static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ + int ft, int fs, int cc)\ +{ \ +TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \ +TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \ +switch (ifmt) { \ +case FMT_PS: \ +check_cp1_64bitmode(ctx); \ +break;\ +case FMT_D: \ +if (abs) \ +check_cop1x(ctx); \ +check_cp1_registers(ctx, fs | ft);\ +break;\ +case FMT_S: \ +if (abs) \ +check_cop1x(ctx
[Qemu-devel] [PATCH 00/10] target-mips: add microMIPS ASE support, v2
This patch series adds support for the microMIPS ASE. microMIPS is a new ASE similar to MIPS16, but re-encodes the entire instruction set into 16-bit and 32-bit instructions--in contrast to MIPS16, which re-encodes only integer instructions. The mechanisms for going in and out of microMIPS mode are identical to those for MIPS16; a given chip cannot support both ASEs simultaneously. changes from v1: fix re-introduction of previously deleted code noted by rth Nathan Froyd (10): target-mips: break out [ls][wd]c1 and rdhwr insn generation target-mips: add microMIPS-specific bits to mips-defs.h target-mips: add enum constants for various invocations of FOP target-mips: refactor {c,abs}.cond.fmt insns target-mips: small changes to use new FMT_ enums target-mips: add microMIPS ASE support target-mips: add microMIPS CPUs target-mips: add microMIPS exception handler support linux-user: honor low bit of entry PC for MIPS hw: honor low bit in mipssim machine hw/mips_mipssim.c|4 +- linux-user/main.c|4 +- target-mips/cpu.h|3 + target-mips/helper.c | 21 +- target-mips/helper.h |9 + target-mips/mips-defs.h |1 + target-mips/op_helper.c | 136 ++ target-mips/translate.c | 3050 ++ target-mips/translate_init.c | 61 + 9 files changed, 3047 insertions(+), 242 deletions(-)
[Qemu-devel] [PATCH 10/10] hw: honor low bit in mipssim machine
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- hw/mips_mipssim.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c index a747de5..cd6c2be 100644 --- a/hw/mips_mipssim.c +++ b/hw/mips_mipssim.c @@ -106,7 +106,9 @@ static void main_cpu_reset(void *opaque) CPUState *env = s-env; cpu_reset(env); -env-active_tc.PC = s-vector; +env-active_tc.PC = s-vector ~(target_ulong)1; +if (s-vector 1) +env-hflags |= MIPS_HFLAG_M16; } static void -- 1.6.3.2
[Qemu-devel] [PATCH 08/10] target-mips: add microMIPS exception handler support
Unlike MIPS16, microMIPS lets you choose the ISA mode for your exception handlers. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/helper.c | 21 +++-- 1 files changed, 15 insertions(+), 6 deletions(-) diff --git a/target-mips/helper.c b/target-mips/helper.c index 8102f03..90c3b3a 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -385,6 +385,18 @@ static target_ulong exception_resume_pc (CPUState *env) return bad_pc; } +static void set_hflags_for_handler (CPUState *env) +{ +/* Exception handlers are entered in 32-bit mode. */ +env-hflags = ~(MIPS_HFLAG_M16); +/* ...except that microMIPS lets you choose. */ +if (env-insn_flags ASE_MICROMIPS) { +env-hflags |= (!!(env-CP0_Config3 +(1 CP0C3_ISA_ON_EXC)) + MIPS_HFLAG_M16_SHIFT); +} +} + #endif void do_interrupt (CPUState *env) @@ -440,8 +452,7 @@ void do_interrupt (CPUState *env) if (!(env-CP0_Status (1 CP0St_EXL))) env-CP0_Cause = ~(1 CP0Ca_BD); env-active_tc.PC = (int32_t)0xBFC00480; -/* Exception handlers are entered in 32-bit mode. */ -env-hflags = ~(MIPS_HFLAG_M16); +set_hflags_for_handler(env); break; case EXCP_RESET: cpu_reset(env); @@ -461,8 +472,7 @@ void do_interrupt (CPUState *env) if (!(env-CP0_Status (1 CP0St_EXL))) env-CP0_Cause = ~(1 CP0Ca_BD); env-active_tc.PC = (int32_t)0xBFC0; -/* Exception handlers are entered in 32-bit mode. */ -env-hflags = ~(MIPS_HFLAG_M16); +set_hflags_for_handler(env); break; case EXCP_EXT_INTERRUPT: cause = 0; @@ -581,8 +591,7 @@ void do_interrupt (CPUState *env) env-active_tc.PC = (int32_t)(env-CP0_EBase ~0x3ff); } env-active_tc.PC += offset; -/* Exception handlers are entered in 32-bit mode. */ -env-hflags = ~(MIPS_HFLAG_M16); +set_hflags_for_handler(env); env-CP0_Cause = (env-CP0_Cause ~(0x1f CP0Ca_EC)) | (cause CP0Ca_EC); break; default: -- 1.6.3.2
[Qemu-devel] [PATCH 07/10] target-mips: add microMIPS CPUs
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate_init.c | 61 ++ 1 files changed, 61 insertions(+), 0 deletions(-) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index b79ed56..8e17f4b 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -141,6 +141,25 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_FMT, }, { +.name = 4Km-micromips, +.CP0_PRid = 0x00018300, +/* Config1 implemented, fixed mapping MMU, + no virtual icache, uncached coherency. */ +.CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | + (0 CP0C1_IS) | (3 CP0C1_IL) | (1 CP0C1_IA) | + (0 CP0C1_DS) | (3 CP0C1_DL) | (1 CP0C1_DA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3, +.SYNCI_Step = 32, +.CCRes = 2, +.CP0_Status_rw_bitmask = 0x1258FF17, +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, +.mmu_type = MMU_TYPE_FMT, +}, +{ .name = 4KEcR1, .CP0_PRid = 0x00018400, .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 CP0C0_MT), @@ -245,6 +264,25 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +.name = 24Kc-micromips, +.CP0_PRid = 0x00019300, +.CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | +(MMU_TYPE_R4000 CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | (15 CP0C1_MMU) | + (0 CP0C1_IS) | (3 CP0C1_IL) | (1 CP0C1_IA) | + (0 CP0C1_DS) | (3 CP0C1_DL) | (1 CP0C1_DA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3 | (0 CP0C3_VInt), +.SYNCI_Step = 32, +.CCRes = 2, +/* No DSP implemented. */ +.CP0_Status_rw_bitmask = 0x1278FF1F, +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, +.mmu_type = MMU_TYPE_R4000, +}, +{ .name = 24Kf, .CP0_PRid = 0x00019300, .CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | @@ -269,6 +307,29 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +.name = 24Kf-micromips, +.CP0_PRid = 0x00019300, +.CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | +(MMU_TYPE_R4000 CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | (1 CP0C1_FP) | (15 CP0C1_MMU) | + (0 CP0C1_IS) | (3 CP0C1_IL) | (1 CP0C1_IA) | + (0 CP0C1_DS) | (3 CP0C1_DL) | (1 CP0C1_DA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3 | (0 CP0C3_VInt), +.CP0_LLAddr_rw_bitmask = 0, +.CP0_LLAddr_shift = 4, +.SYNCI_Step = 32, +.CCRes = 2, +/* No DSP implemented. */ +.CP0_Status_rw_bitmask = 0x3678FF1F, +.CP1_fcr0 = (1 FCR0_F64) | (1 FCR0_L) | (1 FCR0_W) | +(1 FCR0_D) | (1 FCR0_S) | (0x93 FCR0_PRID), +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, +.mmu_type = MMU_TYPE_R4000, +}, +{ .name = 34Kf, .CP0_PRid = 0x00019500, .CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | -- 1.6.3.2
[Qemu-devel] [PATCH 09/10] linux-user: honor low bit of entry PC for MIPS
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- linux-user/main.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 18b52c0..76d443b 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3192,7 +3192,9 @@ int main(int argc, char **argv, char **envp) for(i = 0; i 32; i++) { env-active_tc.gpr[i] = regs-regs[i]; } -env-active_tc.PC = regs-cp0_epc; +env-active_tc.PC = regs-cp0_epc ~(target_ulong)1; +if (regs-cp0_epc 1) +env-hflags |= MIPS_HFLAG_M16; } #elif defined(TARGET_SH4) { -- 1.6.3.2
[Qemu-devel] [PATCH 02/10] target-mips: add microMIPS-specific bits to mips-defs.h
There's a new ASE_MICROMIPS instruction flag, and some extra CP0_Config3 fields. The ISA and ISA_ON_EXC fields are specific to microMIPS. The DSP2P is for version 2 of the DSP ASE. Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/cpu.h |3 +++ target-mips/mips-defs.h |1 + 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 7285636..986d938 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -363,6 +363,9 @@ struct CPUMIPSState { #define CP0C2_SA 0 int32_t CP0_Config3; #define CP0C3_M31 +#define CP0C3_ISA_ON_EXC 16 +#define CP0C3_ISA 14 +#define CP0C3_DSP2P 11 #define CP0C3_DSPP 10 #define CP0C3_LPA 7 #define CP0C3_VEIC 6 diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h index c57de02..a7f4697 100644 --- a/target-mips/mips-defs.h +++ b/target-mips/mips-defs.h @@ -38,6 +38,7 @@ #defineASE_DSPR2 0x0001 #defineASE_MT 0x0002 #defineASE_SMARTMIPS 0x0004 +#defineASE_MICROMIPS 0x0008 /* Chip specific instructions. */ #defineINSN_VR54XX 0x8000 -- 1.6.3.2
[Qemu-devel] [PATCH 10/10] hw: honor low bit in mipssim machine
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- hw/mips_mipssim.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c index a747de5..cd6c2be 100644 --- a/hw/mips_mipssim.c +++ b/hw/mips_mipssim.c @@ -106,7 +106,9 @@ static void main_cpu_reset(void *opaque) CPUState *env = s-env; cpu_reset(env); -env-active_tc.PC = s-vector; +env-active_tc.PC = s-vector ~(target_ulong)1; +if (s-vector 1) +env-hflags |= MIPS_HFLAG_M16; } static void -- 1.6.3.2
[Qemu-devel] [PATCH 00/10] target-mips: add microMIPS ASE support
This patch series adds support for the microMIPS ASE. microMIPS is a new ASE similar to MIPS16, but re-encodes the entire instruction set into 16-bit and 32-bit instructions--in contrast to MIPS16, which re-encodes only integer instructions. The mechanisms for going in and out of microMIPS mode are identical to those for MIPS16; a given chip cannot support both ASEs simultaneously. The first half of the series consists of small refactorings to make it easier to delegate microMIPS instruction decoding to the usual gen_* functions. The second half adds support for microMIPS in all the necessary places. The patch has been tested extensively in our QEMU tree; this patch has been tested against our compilers (GNU/Linux emulation), which include microMIPS support. We have obtained identical test results for MIPS32 and microMIPS testing. (The microMIPS patch for binutils has been posted upstream; the microMIPS patch for GCC is forthcoming.) It is possible to boot kernels compiled for microMIPS, but we have been unsuccessful in consistently being able to do so, and have not yet tracked down the root issue(s). Nathan Froyd (10): target-mips: break out [ls][wd]c1 and rdhwr insn generation target-mips: add microMIPS-specific bits to mips-defs.h target-mips: add enum constants for various invocations of FOP target-mips: refactor {c,abs}.cond.fmt insns target-mips: small changes to use new FMT_ enums target-mips: add microMIPS ASE support target-mips: add microMIPS CPUs target-mips: add microMIPS exception handler support linux-user: honor low bit of entry PC for MIPS hw: honor low bit in mipssim machine hw/mips_mipssim.c|4 +- linux-user/main.c|4 +- target-mips/cpu.h|3 + target-mips/helper.c | 21 +- target-mips/helper.h |9 + target-mips/mips-defs.h |1 + target-mips/op_helper.c | 136 ++ target-mips/translate.c | 3050 ++ target-mips/translate_init.c | 61 + 9 files changed, 3047 insertions(+), 242 deletions(-)
[Qemu-devel] [PATCH 07/10] target-mips: add microMIPS CPUs
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate_init.c | 61 ++ 1 files changed, 61 insertions(+), 0 deletions(-) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index b79ed56..8e17f4b 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -141,6 +141,25 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_FMT, }, { +.name = 4Km-micromips, +.CP0_PRid = 0x00018300, +/* Config1 implemented, fixed mapping MMU, + no virtual icache, uncached coherency. */ +.CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | + (0 CP0C1_IS) | (3 CP0C1_IL) | (1 CP0C1_IA) | + (0 CP0C1_DS) | (3 CP0C1_DL) | (1 CP0C1_DA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3, +.SYNCI_Step = 32, +.CCRes = 2, +.CP0_Status_rw_bitmask = 0x1258FF17, +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, +.mmu_type = MMU_TYPE_FMT, +}, +{ .name = 4KEcR1, .CP0_PRid = 0x00018400, .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 CP0C0_MT), @@ -245,6 +264,25 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +.name = 24Kc-micromips, +.CP0_PRid = 0x00019300, +.CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | +(MMU_TYPE_R4000 CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | (15 CP0C1_MMU) | + (0 CP0C1_IS) | (3 CP0C1_IL) | (1 CP0C1_IA) | + (0 CP0C1_DS) | (3 CP0C1_DL) | (1 CP0C1_DA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3 | (0 CP0C3_VInt), +.SYNCI_Step = 32, +.CCRes = 2, +/* No DSP implemented. */ +.CP0_Status_rw_bitmask = 0x1278FF1F, +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, +.mmu_type = MMU_TYPE_R4000, +}, +{ .name = 24Kf, .CP0_PRid = 0x00019300, .CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | @@ -269,6 +307,29 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +.name = 24Kf-micromips, +.CP0_PRid = 0x00019300, +.CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | +(MMU_TYPE_R4000 CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | (1 CP0C1_FP) | (15 CP0C1_MMU) | + (0 CP0C1_IS) | (3 CP0C1_IL) | (1 CP0C1_IA) | + (0 CP0C1_DS) | (3 CP0C1_DL) | (1 CP0C1_DA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3 | (0 CP0C3_VInt), +.CP0_LLAddr_rw_bitmask = 0, +.CP0_LLAddr_shift = 4, +.SYNCI_Step = 32, +.CCRes = 2, +/* No DSP implemented. */ +.CP0_Status_rw_bitmask = 0x3678FF1F, +.CP1_fcr0 = (1 FCR0_F64) | (1 FCR0_L) | (1 FCR0_W) | +(1 FCR0_D) | (1 FCR0_S) | (0x93 FCR0_PRID), +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, +.mmu_type = MMU_TYPE_R4000, +}, +{ .name = 34Kf, .CP0_PRid = 0x00019500, .CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR) | -- 1.6.3.2
[Qemu-devel] [PATCH 05/10] target-mips: small changes to use new FMT_ enums
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate.c | 17 + 1 files changed, 9 insertions(+), 8 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 8a7f3e9..c42d8dd 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -359,7 +359,8 @@ enum { /* 0 - 15 are reserved */ FMT_S = 16, FMT_D = 17, -/* 18 - 19 are reserved */ +FMT_E = 18, +FMT_Q = 19, FMT_W = 20, FMT_L = 21, FMT_PS = 22, @@ -378,13 +379,13 @@ enum { OPC_BC1 = (0x08 21) | OPC_CP1, /* bc */ OPC_BC1ANY2 = (0x09 21) | OPC_CP1, OPC_BC1ANY4 = (0x0A 21) | OPC_CP1, -OPC_S_FMT= (0x10 21) | OPC_CP1, /* 16: fmt=single fp */ -OPC_D_FMT= (0x11 21) | OPC_CP1, /* 17: fmt=double fp */ -OPC_E_FMT= (0x12 21) | OPC_CP1, /* 18: fmt=extended fp */ -OPC_Q_FMT= (0x13 21) | OPC_CP1, /* 19: fmt=quad fp */ -OPC_W_FMT= (0x14 21) | OPC_CP1, /* 20: fmt=32bit fixed */ -OPC_L_FMT= (0x15 21) | OPC_CP1, /* 21: fmt=64bit fixed */ -OPC_PS_FMT = (0x16 21) | OPC_CP1, /* 22: fmt=paired single fp */ +OPC_S_FMT= (FMT_S 21) | OPC_CP1, /* 16: fmt=single fp */ +OPC_D_FMT= (FMT_D 21) | OPC_CP1, /* 17: fmt=double fp */ +OPC_E_FMT= (FMT_E 21) | OPC_CP1, /* 18: fmt=extended fp */ +OPC_Q_FMT= (FMT_Q 21) | OPC_CP1, /* 19: fmt=quad fp */ +OPC_W_FMT= (FMT_W 21) | OPC_CP1, /* 20: fmt=32bit fixed */ +OPC_L_FMT= (FMT_L 21) | OPC_CP1, /* 21: fmt=64bit fixed */ +OPC_PS_FMT = (FMT_PS 21) | OPC_CP1, /* 22: fmt=paired single fp */ }; #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op 0x3F) -- 1.6.3.2
[Qemu-devel] [PATCH 01/10] target-mips: break out [ls][wd]c1 and rdhwr insn generation
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- target-mips/translate.c | 106 ++- 1 files changed, 59 insertions(+), 47 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index c95ecb1..2075d09 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1220,6 +1220,17 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, tcg_temp_free(t0); } +static void gen_cop1_ldst(CPUState *env, DisasContext *ctx, + uint32_t op, int rt, int rs, int16_t imm) +{ +if (env-CP0_Config1 (1 CP0C1_FP)) { +check_cp1_enabled(ctx); +gen_flt_ldst(ctx, op, rt, rs, imm); +} else { +generate_exception_err(ctx, EXCP_CpU, 1); +} +} + /* Arithmetic with immediate operand */ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rs, int16_t imm) @@ -7528,6 +7539,52 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, fregnames[fs], fregnames[ft]); } +static void +gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd) +{ +TCGv t0; + +check_insn(env, ctx, ISA_MIPS32R2); +t0 = tcg_temp_new(); + +switch (rd) { +case 0: +save_cpu_state(ctx, 1); +gen_helper_rdhwr_cpunum(t0); +gen_store_gpr(t0, rt); +break; +case 1: +save_cpu_state(ctx, 1); +gen_helper_rdhwr_synci_step(t0); +gen_store_gpr(t0, rt); +break; +case 2: +save_cpu_state(ctx, 1); +gen_helper_rdhwr_cc(t0); +gen_store_gpr(t0, rt); +break; +case 3: +save_cpu_state(ctx, 1); +gen_helper_rdhwr_ccres(t0); +gen_store_gpr(t0, rt); +break; +case 29: +#if defined(CONFIG_USER_ONLY) +tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); +gen_store_gpr(t0, rt); +break; +#else +/* XXX: Some CPUs implement this in hardware. + Not supported yet. */ +#endif +default:/* Invalid */ +MIPS_INVAL(rdhwr); +generate_exception(ctx, EXCP_RI); +break; +} +tcg_temp_free(t0); +} + static void handle_delay_slot (CPUState *env, DisasContext *ctx, int insn_bytes) { @@ -8999,47 +9056,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch) gen_bshfl(ctx, op2, rt, rd); break; case OPC_RDHWR: -check_insn(env, ctx, ISA_MIPS32R2); -{ -TCGv t0 = tcg_temp_new(); - -switch (rd) { -case 0: -save_cpu_state(ctx, 1); -gen_helper_rdhwr_cpunum(t0); -gen_store_gpr(t0, rt); -break; -case 1: -save_cpu_state(ctx, 1); -gen_helper_rdhwr_synci_step(t0); -gen_store_gpr(t0, rt); -break; -case 2: -save_cpu_state(ctx, 1); -gen_helper_rdhwr_cc(t0); -gen_store_gpr(t0, rt); -break; -case 3: -save_cpu_state(ctx, 1); -gen_helper_rdhwr_ccres(t0); -gen_store_gpr(t0, rt); -break; -case 29: -#if defined(CONFIG_USER_ONLY) -tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); -gen_store_gpr(t0, rt); -break; -#else -/* XXX: Some CPUs implement this in hardware. - Not supported yet. */ -#endif -default:/* Invalid */ -MIPS_INVAL(rdhwr); -generate_exception(ctx, EXCP_RI); -break; -} -tcg_temp_free(t0); -} +gen_rdhwr(env, ctx, rt, rd); break; case OPC_FORK: check_insn(env, ctx, ASE_MT); @@ -9242,12 +9259,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch) case OPC_LDC1: case OPC_SWC1: case OPC_SDC1: -if (env-CP0_Config1 (1 CP0C1_FP)) { -check_cp1_enabled(ctx); -gen_flt_ldst(ctx, op, rt, rs, imm); -} else { -generate_exception_err(ctx, EXCP_CpU, 1); -} +gen_cop1_ldst(env, ctx, op, rt, rs, imm); break; case OPC_CP1: -- 1.6.3.2
[Qemu-devel] [PATCH 09/10] linux-user: honor low bit of entry PC for MIPS
Signed-off-by: Nathan Froyd froy...@codesourcery.com --- linux-user/main.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 18b52c0..76d443b 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3192,7 +3192,9 @@ int main(int argc, char **argv, char **envp) for(i = 0; i 32; i++) { env-active_tc.gpr[i] = regs-regs[i]; } -env-active_tc.PC = regs-cp0_epc; +env-active_tc.PC = regs-cp0_epc ~(target_ulong)1; +if (regs-cp0_epc 1) +env-hflags |= MIPS_HFLAG_M16; } #elif defined(TARGET_SH4) { -- 1.6.3.2