Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/lib/libunwind GCC 5.3 likes to emit unwind data with flo...



details:   https://anonhg.NetBSD.org/src/rev/2828419f944b
branches:  trunk
changeset: 825415:2828419f944b
user:      joerg <joerg%NetBSD.org@localhost>
date:      Thu Jul 13 15:13:19 2017 +0000

description:
GCC 5.3 likes to emit unwind data with float registers, i.e. register
halfs. Compensate.

diffstat:

 sys/lib/libunwind/Registers.hpp |  33 ++++++++++++++++++++++++++-------
 1 files changed, 26 insertions(+), 7 deletions(-)

diffs (81 lines):

diff -r a9854ac85ec4 -r 2828419f944b sys/lib/libunwind/Registers.hpp
--- a/sys/lib/libunwind/Registers.hpp   Thu Jul 13 14:10:38 2017 +0000
+++ b/sys/lib/libunwind/Registers.hpp   Thu Jul 13 15:13:19 2017 +0000
@@ -12,6 +12,7 @@
 #ifndef __REGISTERS_HPP__
 #define __REGISTERS_HPP__
 
+#include <sys/endian.h>
 #include <cassert>
 #include <cstdint>
 
@@ -323,8 +324,8 @@
   DWARF_ARM32_R0 = 0,
   DWARF_ARM32_R15 = 15,
   DWARF_ARM32_SPSR = 128,
-  DWARF_ARM32_OLD_S0 = 64,
-  DWARF_ARM32_OLD_S31 = 91,
+  DWARF_ARM32_S0 = 64,
+  DWARF_ARM32_S31 = 91,
   DWARF_ARM32_D0 = 256,
   DWARF_ARM32_D31 = 287,
   REGNO_ARM32_R0 = 0,
@@ -334,6 +335,8 @@
   REGNO_ARM32_D0 = 17,
   REGNO_ARM32_D15 = 32,
   REGNO_ARM32_D31 = 48,
+  REGNO_ARM32_S0 = 49,
+  REGNO_ARM32_S31 = 70,
 };
 
 class Registers_arm32 {
@@ -354,9 +357,8 @@
       return REGNO_ARM32_SPSR;
     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
-    if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) {
-      assert(num % 2 == 0);
-      return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2;
+    if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) {
+      return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0);
     }
     return LAST_REGISTER + 1;
   }
@@ -384,10 +386,28 @@
   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
 
   bool validFloatVectorRegister(int num) const {
-    return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
+    return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31);
   }
 
   void copyFloatVectorRegister(int num, uint64_t addr_) {
+    const void *addr = reinterpret_cast<const void *>(addr_);
+    if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
+      if ((flags & 1) == 0) {
+        lazyVFP1();
+        flags |= 1;
+      }
+      /*
+       * Emulate single precision register as half of the
+       * corresponding double register.
+       */
+      int dnum = (num - REGNO_ARM32_S0) / 2;
+      int part = (num - REGNO_ARM32_S0) % 2;
+#if _BYTE_ORDER == _BIG_ENDIAN
+      part = 1 - part;
+#endif
+      memcpy(fpreg + dnum + part * sizeof(fpreg[0]) / 2,
+        addr, sizeof(fpreg[0]) / 2);
+    }
     if (num <= REGNO_ARM32_D15) {
       if ((flags & 1) == 0) {
         lazyVFP1();
@@ -399,7 +419,6 @@
         flags |= 2;
       }
     }
-    const void *addr = reinterpret_cast<const void *>(addr_);
     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
   }
 



Home | Main Index | Thread Index | Old Index