diff mbox

[v3,1/2] target-mips: Rework ABIs to allow all required configurations

Message ID alpine.DEB.1.10.1412121814440.19155@tp.orcam.me.uk
State New
Headers show

Commit Message

Maciej W. Rozycki Dec. 12, 2014, 6:27 p.m. UTC
Rework the MIPS ABIs and CPU emulations available according to the 
following target list:

- mips|mipsel       -- 32-bit CPUs only, system and user emulation mode, 
                       o32 user ABI,

- mips64|mips64el   -- 32-bit and 64-bit CPUs, system and user emulation 
                       mode, o32 user ABI,

- mipsn32|mipsn32el -- 64-bit CPUs only, user emulation mode only, n32 
                       user ABI,

- mipsn64|mipsn64el -- 64-bit CPUs only, user emulation mode only, n64 
                       user ABI.

Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com>
---
Changes from v1:

- remove n32 and n64 system emulation mode configurations,

- fold 1/3 and 2/3 into 1/2.

Changes from v2:

- only set the CP0.Status.FR bit for 64-bit ABIs rather than all 64-bit 
  configurations (translate.c).

 Strictly speaking the mask check should be an assertion failure or 
suchlike, because all 64-bit processors must support having this bit set 
to 1.  This will also require further updates for the FRXX ABI (where 
the bit indeed has to be set to 1 where possible) and R6 processors 
(where the bit is hardwired to 1 and will therefore fail the mask 
check).

 For the time being, the change is a move in the right direction, o32 
user mode emulation must not set this bit merely because it is writable.  
I'll check yet how this bug (that I missed) affected IEEE 754-2008 NaN 
testing, but I will only have results on Monday at the earliest.

  Maciej

qemu-mips64-abis.diff
diff mbox

Patch

Index: qemu-git-trunk/bsd-user/elfload.c
===================================================================
--- qemu-git-trunk.orig/bsd-user/elfload.c	2014-12-12 18:05:17.000000000 +0000
+++ qemu-git-trunk/bsd-user/elfload.c	2014-12-12 18:05:29.138927913 +0000
@@ -381,7 +381,7 @@  static inline void init_thread(struct ta
 
 #define elf_check_arch(x) ( (x) == EM_MIPS )
 
-#ifdef TARGET_MIPS64
+#ifdef TARGET_ABI_MIPSN64
 #define ELF_CLASS   ELFCLASS64
 #else
 #define ELF_CLASS   ELFCLASS32
Index: qemu-git-trunk/configure
===================================================================
--- qemu-git-trunk.orig/configure	2014-12-12 18:05:17.000000000 +0000
+++ qemu-git-trunk/configure	2014-12-12 18:05:29.138927913 +0000
@@ -4982,7 +4982,7 @@  target_name=`echo $target | cut -d '-' -
 target_bigendian="no"
 
 case "$target_name" in
-  armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
+  armeb|lm32|m68k|microblaze|mips|mips64|mipsn32|mipsn64|moxie|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
   ;;
 esac
@@ -5057,17 +5057,28 @@  case "$target_name" in
   ;;
   mips|mipsel)
     TARGET_ARCH=mips
+    echo "TARGET_MIPS32=y" >> $config_target_mak
     echo "TARGET_ABI_MIPSO32=y" >> $config_target_mak
   ;;
+  mips64|mips64el)
+    TARGET_ARCH=mips64
+    TARGET_BASE_ARCH=mips
+    TARGET_ABI_DIR=mips
+    echo "TARGET_MIPS32=y" >> $config_target_mak
+    echo "TARGET_ABI_MIPSO32=y" >> $config_target_mak
+    echo "TARGET_ABI32=y" >> $config_target_mak
+  ;;
   mipsn32|mipsn32el)
     TARGET_ARCH=mips64
     TARGET_BASE_ARCH=mips
+    TARGET_ABI_DIR=mips64
     echo "TARGET_ABI_MIPSN32=y" >> $config_target_mak
     echo "TARGET_ABI32=y" >> $config_target_mak
   ;;
-  mips64|mips64el)
+  mipsn64|mipsn64el)
     TARGET_ARCH=mips64
     TARGET_BASE_ARCH=mips
+    TARGET_ABI_DIR=mips64
     echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
   ;;
   tricore)
Index: qemu-git-trunk/default-configs/mipsn64-linux-user.mak
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ qemu-git-trunk/default-configs/mipsn64-linux-user.mak	2014-12-12 18:05:29.138927913 +0000
@@ -0,0 +1 @@ 
+# Default configuration for mipsn64-linux-user
Index: qemu-git-trunk/default-configs/mipsn64el-linux-user.mak
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ qemu-git-trunk/default-configs/mipsn64el-linux-user.mak	2014-12-12 18:05:29.138927913 +0000
@@ -0,0 +1 @@ 
+# Default configuration for mipsn64el-linux-user
Index: qemu-git-trunk/include/exec/poison.h
===================================================================
--- qemu-git-trunk.orig/include/exec/poison.h	2014-12-12 18:05:17.000000000 +0000
+++ qemu-git-trunk/include/exec/poison.h	2014-12-12 18:05:29.138927913 +0000
@@ -13,7 +13,11 @@ 
 #pragma GCC poison TARGET_LM32
 #pragma GCC poison TARGET_M68K
 #pragma GCC poison TARGET_MIPS
+#pragma GCC poison TARGET_MIPS32
 #pragma GCC poison TARGET_MIPS64
+#pragma GCC poison TARGET_ABI_MIPSO32
+#pragma GCC poison TARGET_ABI_MIPSN32
+#pragma GCC poison TARGET_ABI_MIPSN64
 #pragma GCC poison TARGET_OPENRISC
 #pragma GCC poison TARGET_PPC
 #pragma GCC poison TARGET_PPCEMB
Index: qemu-git-trunk/linux-user/elfload.c
===================================================================
--- qemu-git-trunk.orig/linux-user/elfload.c	2014-12-12 18:05:17.000000000 +0000
+++ qemu-git-trunk/linux-user/elfload.c	2014-12-12 18:05:29.138927913 +0000
@@ -875,7 +875,7 @@  static void elf_core_copy_regs(target_el
 
 #define elf_check_arch(x) ( (x) == EM_MIPS )
 
-#ifdef TARGET_MIPS64
+#ifdef TARGET_ABI_MIPSN64
 #define ELF_CLASS   ELFCLASS64
 #else
 #define ELF_CLASS   ELFCLASS32
@@ -896,10 +896,10 @@  typedef target_elf_greg_t target_elf_gre
 
 /* See linux kernel: arch/mips/include/asm/reg.h.  */
 enum {
-#ifdef TARGET_MIPS64
-    TARGET_EF_R0 = 0,
-#else
+#ifdef TARGET_ABI_MIPSO32
     TARGET_EF_R0 = 6,
+#else
+    TARGET_EF_R0 = 0,
 #endif
     TARGET_EF_R26 = TARGET_EF_R0 + 26,
     TARGET_EF_R27 = TARGET_EF_R0 + 27,
Index: qemu-git-trunk/linux-user/main.c
===================================================================
--- qemu-git-trunk.orig/linux-user/main.c	2014-12-12 18:05:17.000000000 +0000
+++ qemu-git-trunk/linux-user/main.c	2014-12-12 18:05:29.138927913 +0000
@@ -3928,7 +3928,7 @@  int main(int argc, char **argv, char **e
         cpu_model = "Fujitsu MB86904";
 #endif
 #elif defined(TARGET_MIPS)
-#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
+#ifdef TARGET_MIPS64
         cpu_model = "5KEf";
 #else
         cpu_model = "24Kf";
Index: qemu-git-trunk/target-mips/translate.c
===================================================================
--- qemu-git-trunk.orig/target-mips/translate.c	2014-12-12 18:05:26.000000000 +0000
+++ qemu-git-trunk/target-mips/translate.c	2014-12-12 18:05:52.148080884 +0000
@@ -19533,8 +19533,9 @@  void cpu_state_reset(CPUMIPSState *env)
     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
         env->CP0_Status |= (1 << CP0St_MX);
     }
-# if defined(TARGET_MIPS64)
-    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
+# if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
+    /* For 64-bit ABIs, init the FR bit to 1 if the FPU unit is there
+       and the bit is writable.  */
     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
         env->CP0_Status |= (1 << CP0St_FR);
Index: qemu-git-trunk/target-mips/translate_init.c
===================================================================
--- qemu-git-trunk.orig/target-mips/translate_init.c	2014-12-12 18:05:17.000000000 +0000
+++ qemu-git-trunk/target-mips/translate_init.c	2014-12-12 18:05:29.138927913 +0000
@@ -107,6 +107,7 @@  struct mips_def_t {
 /* MIPS CPU definitions */
 static const mips_def_t mips_defs[] =
 {
+#if defined(TARGET_MIPS32)
     {
         .name = "4Kc",
         .CP0_PRid = 0x00018000,
@@ -421,6 +422,7 @@  static const mips_def_t mips_defs[] =
         .insn_flags = CPU_MIPS32R5 | ASE_MIPS16 | ASE_MSA,
         .mmu_type = MMU_TYPE_R4000,
     },
+#endif
 #if defined(TARGET_MIPS64)
     {
         .name = "R4000",