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 <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Add instruction decoding for the microMIPS ASE. All we do is decode and
then forward to the existing gen_* routines.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
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 <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Move all knowledge about coprocessor-checking and register numbering
into the gen_cmp* helper functions.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
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 <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
In the previous patch which introduced fprintf_function to
allow parameter checking by gcc some compiler warnings
remained unfixed.
These warnings are fixed here.
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
QEMU uses a fixed page size for the CPU TLB. If the guest uses large
pages then we effectively split these into multiple smaller pages, and
populate the corresponding TLB entries on demand.
When the guest invalidates the TLB by virtual address we must invalidate
all entries covered by the large page. However the address used to
invalidate the entry may not be present in the QEMU TLB, so we do not
know which regions to clear.
Implementing a full vaiable size TLB is hard and slow, so just keep a
simple address/mask pair to record which addresses may have been mapped by
large pages. If the guest invalidates this region then flush the
whole TLB.
Signed-off-by: Paul Brook <paul@codesourcery.com>
Removes a set of ifdefs from exec.c.
Introduce TARGET_VIRT_ADDR_SPACE_BITS for all targets other
than Alpha. This will be used for page_find_alloc, which is
supposed to be using virtual addresses in the first place.
Signed-off-by: Richard Henderson <rth@twiddle.net>
When we signal a CpU exception for coprocessor 0, we should indicate
that it's for coprocessor 0 instead of coprocessor 1.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
In helper.c AREG0 may not correspond do env, so it's not possible to
call cpu_loop_exit() here. Call it from op_helper.c instead.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Fix regression introduced by d19954f46d.
4Kc and 4KEc don't support MIPS16.
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
4Kc, 4KEc cores do not support MIPS16, so not only the
CP0_Config1 had to be fixed (see previous patch),
but also MIPS16 instructions must not be executed.
(Hint from Nathan Froyd, thanks).
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Running programs with the MIPS user-mode emulator fails during dynamic
loading, as floating-point instructions are not enabled in in
env->hflags. Move the code for doing so from fpu_init to cpu_reset so
the MIPS_HFLAG_{FPU,F64} setting doesn't get clobbered by cpu_reset
setting env->hflags to MIPS_HFLAG_UM.
The same end can be achieved by swapping the ordering of fpu_init and
cpu_reset in cpu_mips_init, but it seemed better to consolidate the
CONFIG_USER_ONLY code into a single location.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
There's no good way to add this incrementally, so we do it all at once.
The only changes to shared code are in handle_delay_slot. We need to
flip ISAMode when doing a jump-and-exchange. We also need to set
ISAMode the low bit of the target address for jump-to-register.
Also, since we're now adding bits that can be in MIPS_HFLAG_BMASK_EXT,
make sure we use MIPS_HFLAG_BMASK_BASE in the places where we just want
basic information about a branch.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Move delay slot handling to common code whose invocation can be
controlled from gen_intermediate_code_internal.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This is a common pattern in existing code. We'll also use it to
implement the mips16 SAVE/RESTORE instructions.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
It's easier to implement mips16 shift instructions if we're not
examining the opcode inside gen_shift_{imm,}. So move ROTR and ROTRV
and do the special-case handling of SRL and SRLV inside decode_opc.
Likewise for their 64-bit counterparts.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
We need to stash the operating mode into the low bit of the error PC and
restore it on return from interrupts.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
We create separate masks for the "basic" branch hflags and the
"extended" branch hflags and define MIPS_HFLAG_BMASK as the logical or
of those two. This is done to avoid churning the codebase in lots of
different places.
We also make the execution mode an hflag under MIPS_HFLAG_TMASK
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Currently the ll/sc instructions use the virtual address in both
user and system mode. Use the physical address insteead in system
mode.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Depending on the CPU, CP0_LLAddr is either read-only or read-write,
and the returned value can be shifted by a variable amount of bits.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
The variable CP0_LLAddr represent the full lladdr, not the actual
register value, which is only part of this value and depends on the
CPU.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>