error: the register ‘’ cannot be clobbered in ‘asm’ for the current target

Question

cd valgrind-3.22.0
./configure --host=mipsel-linux

[...]

priv/guest_mips_helpers.c: In function ‘mips_dirtyhelper_calculate_FCSR_fp32’:
priv/guest_mips_helpers.c:497:4: error: the register ‘$f21’ cannot be clobbered in ‘asm’ for the current target
  497 |    __asm__ volatile(".set  push"        "\n\t"                      \
      |    ^~~~~~~
priv/guest_mips_helpers.c:640:10: note: in expansion of macro ‘ASM_VOLATILE_UNARY32_DOUBLE’
  640 |          ASM_VOLATILE_UNARY32_DOUBLE(round.w.d)
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~
priv/guest_mips_helpers.c:482:4: error: the register ‘$f20’ cannot be clobbered in ‘asm’ for the current target
  482 |    __asm__ volatile(".set  push"        "\n\t"                      \
      |    ^~~~~~~
priv/guest_mips_helpers.c:643:10: note: in expansion of macro ‘ASM_VOLATILE_UNARY32’
  643 |          ASM_VOLATILE_UNARY32(floor.w.s)
      |          ^~~~~~~~~~~~~~~~~~~~
priv/guest_mips_helpers.c:497:4: error: the register ‘$f21’ cannot be clobbered in ‘asm’ for the current target
  497 |    __asm__ volatile(".set  push"        "\n\t"                      \
      |    ^~~~~~~
priv/guest_mips_helpers.c:646:10: note: in expansion of macro ‘ASM_VOLATILE_UNARY32_DOUBLE’
  646 |          ASM_VOLATILE_UNARY32_DOUBLE(floor.w.d)
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~
priv/guest_mips_helpers.c:482:4: error: the register ‘$f20’ cannot be clobbered in ‘asm’ for the current target
  482 |    __asm__ volatile(".set  push"        "\n\t"                      \
      |    ^~~~~~~

Answer

Apply below patch from openwrt

Disable the valgrind helpers which use MIPS floating point operations 
when floating point support is deactivated in the toolchain.

The fix from this commit is not sufficient any more:
https://sourceware.org/git/?p=valgrind.git;a=commitdiff;h=869fcf2f6739f17b4eff36ec68f8dca826c8afeb

This fixes the following error message when compiling with a GCC 10 MIPS BE 32:
---------------------------------------------------------
../VEX/priv/guest_mips_helpers.c: In function 'mips_dirtyhelper_calculate_FCSR_fp32':
../VEX/priv/guest_mips_helpers.c:640:10: error: the register '$f21' cannot be clobbered in 'asm' for the current target
  640 |          ASM_VOLATILE_UNARY32_DOUBLE(round.w.d)
      |          ^
---------------------------------------------------------

--- a/VEX/priv/guest_mips_helpers.c
+++ b/VEX/priv/guest_mips_helpers.c
@@ -616,6 +616,7 @@ extern UInt mips_dirtyhelper_calculate_F
                                                    flt_op inst )
 {
    UInt ret = 0;
+#ifndef __mips_soft_float
 #if defined(__mips__)
    VexGuestMIPS32State* guest_state = (VexGuestMIPS32State*)gs;
    UInt loFsVal, hiFsVal, loFtVal, hiFtVal;
@@ -698,6 +699,7 @@ extern UInt mips_dirtyhelper_calculate_F
          break;
    }
 #endif
+#endif
    return ret;
 }
 
@@ -707,6 +709,7 @@ extern UInt mips_dirtyhelper_calculate_F
                                                    flt_op inst )
 {
    UInt ret = 0;
+#ifndef __mips_soft_float
 #if defined(__mips__) && ((__mips == 64) ||                                  \
                           (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)))
 #if defined(VGA_mips32)
@@ -859,6 +862,7 @@ extern UInt mips_dirtyhelper_calculate_F
          break;
    }
 #endif
+#endif
    return ret;
 }
 
--- a/coregrind/m_machine.c
+++ b/coregrind/m_machine.c
@@ -2106,6 +2106,7 @@ Bool VG_(machine_get_hwcaps)( void )
            we are using alternative way to determine FP mode */
         ULong result = 0;
 
+#ifndef __mips_soft_float
         if (!VG_MINIMAL_SETJMP(env_unsup_insn)) {
            __asm__ volatile (
               ".set push\n\t"
@@ -2123,6 +2124,9 @@ Bool VG_(machine_get_hwcaps)( void )
 
            fpmode = (result != 0x3FF0000000000000ull);
         }
+#else
+	fpmode = 0;
+#endif
      }
 
      if (fpmode != 0)
0%